Description
十年前,北湖还只是一个深坑,未完成蓄水工作。为了确保蓄水工作的顺利进行,我们需要对北湖的蓄水量进行粗略估计。
为了简化运算,我们假设北湖的地面是一维的,每一块宽度都为1,高度是非负整数,那么可以用一个数组来表达一块地面。
例如数组[0,1,0,2,1,0,1,3,2,1,2,1]可以用来表示下图地面:
Input
样例输入有多组。
第一行输入整数 T 表示有 T 组用例;
接下来,对于每组用例,输入一个正整数 n ,表示地面总宽度为 n 。
接下来一行是 n 个数ai,用空格隔开,表示地面高度。
Output
对于每个用例输出一行一个数字,表示蓄水总量。
测试输入 | 期待的输出 | 时间限制 | 内存限制 | 额外进程 | |
---|---|---|---|---|---|
测试用例 1 | 以文本方式显示
| 以文本方式显示
| 1秒 | 64M | 0 |
思路
本题要求蓄水量,实际就是看每一点左右两侧最大值中较小的,减去自身高度,再求和。
使用了三个数组,分别存储自身高度,左侧最大值,右侧最大值
第一次遍历实现输入数据和找出每个点左侧最大值;
第二次遍历实现找出右侧最大值以及累加蓄水量。
可能有点繁琐,但我觉得对我而言更容易理解
代码
#include<stdio.h>
#define max(a,b) a>b?a:b
#define min(a,b) a>b?b:a
long long int a[100000]={0},left[100000]={0},right[100000]={0};
main()
{
int t,n,i;
long long int sum=0,m;
scanf("%d",&t);
while(t--){
scanf("%d",&n);
/*循环初值*/
sum=0;
left[0]=0;
right[n]=0;
/*输入数据并且求i左侧最大值*/
for(i=1;i<=n;i++){
scanf("%lld",&a[i]);
left[i]=max(left[i-1],a[i-1]);
}
/*求i右侧最大值并计算第i格蓄水量*/
for(i=n-1;i>0;i--){
right[i]=max(right[i+1],a[i+1]);
//printf("%d\t%d\t%d\n",
min(left[i],right[i]),a[i],min(left[i],right[i])-a[i]);
m=(min(left[i],right[i]))-a[i];
if(m>0) sum+=m;
}
printf("%lld\n",sum);
}
}