2016广东工业大学校赛 E题 GDUT-oj1173

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
题意:搭好积木 能装多少水? 题目很好理解
题解:刚开始思路错误 想着不断寻找最高积木与次高积木 然后判断之间能存多少水 TLE
        AC 代码 考虑每一列积木能贡献多少积水 记录当前列的左max与右max
       然后遍历答案ans+=min(l[i],r[i])-a[i];
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<queue>
 6 #include<stack>
 7 #include<map>
 8 #include<set>
 9 #define ll long long 
10 #define Pi acos(-1.0)
11 #define mod 1
12 #define MAX 100000
13 #define bug(x) printf("%d************
",x);
14 using namespace std;
15 #define ll long long
16 int a[1000010];
17 int r[1000010];
18 int l[1000010];
19 int main()
20 {
21     int x,y,z,i,t;
22     scanf("%d",&x);
23     while(x--)
24     {
25         memset(l,0,sizeof(l));
26         memset(r,0,sizeof(r));
27         scanf("%d",&y);
28         for(i=0;i<y;i++)
29         scanf("%d",&a[i]);
30         int maxx=0;
31         for(i=1;i<y;i++)
32         {
33             maxx=max(maxx,a[i-1]);
34             l[i]=maxx;
35         }
36         maxx=0;
37         for(i=y-2;i>=0;i--)
38         {
39             maxx=max(maxx,a[i+1]);
40             r[i]=maxx;
41         }
42         ll ans=0;
43         for(i=0;i<y;i++)
44         {
45             if(min(l[i],r[i])>a[i])
46             ans+=min(l[i],r[i])-a[i];
47         }
48         printf("%lld
",ans);
49     }
50     return 0;
51 }
52  
53 /**************************************************************
54     Problem: 1173
55     User: 853665920
56     Language: C++
57     Result: Accepted
58     Time:624 ms
59     Memory:13496 kb
60 ****************************************************************/
原文地址:https://www.cnblogs.com/hsd-/p/5376618.html