凹凸不平的地面每当下雨的时候总会积水。假设地面是一维的,每一块宽度都为1,高度是非负整数,那么可以用一个数组来表达一块地面。例如[0,1,0,2,1,0,1,3,2,1,2,1]可以用来表示下图地面:
当下过雨后,地面就会积水,上图中蓝色的区域就是积水区域。现在给你一个数组表示地面,求下过雨后这块地面有多少积水量(假设不蒸发、不渗透)。
Input
第一行是一个整数m,表示有m组试样例,不超过100。
接下来m块,每块第一行是一个正整数n,表示地面总宽度(数组长度),不超过20000。
接下来一行是n个整数,用空格隔开,表示地面高度。
Output
对于每组输入,输出一个整数表示积水量。
Sample Input
2
12
0 1 0 2 1 0 1 3 2 1 2 1
4
1 0 0 2
Sample Output
6
2
思路:
短板效应
积水的多少取决于较低的地面的高度。
如图所示,求出每一栏左边的最高的地面高度和右边的最高的地面的高度,求出两个最高高度的最小值,在用最小值去减当前计算的这一栏的地面高度,如果减过后结果是赋值,则计算积水量时不加,反之,加。
代码:
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
int a[20010];
int left[20010],right[20010];
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int n;
scanf("%d",&n);
for(int i=0; i<n; i++)
scanf("%d",&a[i]);
int max1=0;
for(int i=0; i<n; i++)//求出左边最大
{
left[i]=max1;
if(a[i]>max1)
max1=a[i];
}
int max2=0;
for(int i=n-1; i>=0; i--)//子u出右边最大
{
right[i]=max2;
if(a[i]>max2)
max2=a[i];
}
int sum=0;
for(int i=0; i<n; i++)
{
int x=min(right[i],left[i]);//求出两边最小值
if(x-a[i]>0)
sum+=(x-a[i]);
}
printf("%d\n",sum);
}
return 0;
}