zoukankan      html  css  js  c++  java
  • Problem E: 积木积水 ——————【模拟】

    Problem E: 积木积水

    Description

    现有一堆边长为1的已经放置好的积木,小明(对的,你没看错,的确是陪伴我们成长的那个小明)想知道当下雨天来时会有多少积水。小明又是如此地喜欢二次元,于是他把这个三维的现实问题简化成二维的问题。设雨量无穷、积木不透水、积木间无缝连接,问在这个二次元的世界里,已放置好的积木会有多少单位的积水量?

    Input

    第一行包含一个整数T(T≤100),表示接下来的测试样例个数。 每个测试样例有两行组成: 第一行包含一个整数N(N≤1e6),表示积木的列数; 第二行包含N个整数Ai(Ai≤1e6),表示第i列积木的个数。

    Output

    每个样例输出一行,包含一个整数,为题目所求。

    Sample Input

    1
    11
    6 2 2 4 2 0 3 4 4 5 1

    Sample Output

    19
     
    解题思路:首先找到最高的那个位置,然后向左右找第二高的位置,把这中间的积水算出来,一直往左右去找。
    #include<stdio.h>
    #include<algorithm>
    #include<string.h>
    using namespace std;
    const int maxn = 1e6+200;
    typedef long long LL;
    int a[maxn], bef[maxn], beh[maxn];
    int main(){
        int cas, n;
        scanf("%d",&cas);
        while(cas--){
            memset(bef,0,sizeof(bef));
            memset(beh,0,sizeof(beh));
            scanf("%d",&n);
            int Maxh = 0, Maxid = 1;
            for(int i = 1; i <= n; i++){
                scanf("%d",&a[i]);
                if(bef[i-1] < a[i]){
                    bef[i] = a[i];
                }else{
                    bef[i] = bef[i-1];
                }
                if(a[i]>Maxh){
                    Maxid = i;
                    Maxh = a[i];
                }
            }
            int l = 1, r = n;
            for(int i = 2;i <= n; i++){
                if(a[i] <= a[i-1]){
                    break;
                }else{
                    l = i;
                }
            }
            for(int i = n-1;i >= 1; i--){
                if(a[i] <= a[i+1]){
                    break;
                }else{
                    r = i;
                }
            }
            if(l >= r){
                puts("0"); continue;
            }
            for(int i = n; i >= Maxid; i--){
                if(beh[i+1] > a[i]){
                    beh[i] = beh[i+1];
                }else{
                    beh[i] = a[i];
                }
            }
            LL sum = 0, tmp = 0;
            int  c = 0;
            int hei = Maxh;
            beh[r+1] = -1;
            for(int i = Maxid+1; i <= r; i++){
                if(beh[i]!=beh[i+1]){
                    sum += tmp - (c*(hei-a[i]));
                    hei = a[i];
                    tmp = 0;
                    c = 0;
                }else{
                    tmp += hei - a[i];
                    c++;
                }
            }
            hei = Maxh; tmp = 0; c = 0;
            bef[l-1] = -1;
            for(int i = Maxid-1; i >= l; i--){
                if(bef[i]!=bef[i-1]){
                    sum += tmp - c*(hei-a[i]);
                    hei = a[i];
                    tmp = 0; c = 0;
                }else{
                    tmp += hei - a[i];
                    c++;
                }
            }
            printf("%lld
    ",sum);
        }
        return 0;
    }
    

      

  • 相关阅读:
    LeetCode24-Swap_Pairs
    LeeCode
    LeetCode3-Longest_Substring_Without_Repeating_Characters
    治愈 JavaScript 疲态的学习计划【转载】
    前端冷知识集锦[转载]
    知道这20个正则表达式,能让你少写1,000行代码[转载]
    关于简历和面试【整理自知乎】
    正念冥想方法
    一些职场经验【转载自知乎】
    犹太复国计划向世界展现了一个不一样的民族——观《犹太复国血泪史》有感
  • 原文地址:https://www.cnblogs.com/chengsheng/p/5382220.html
Copyright © 2011-2022 走看看