题目信息
十年前,北湖还只是一个深坑,未完成蓄水工作。为了确保蓄水工作的顺利进行,我们需要对北湖的蓄水量进行粗略估计。
为了简化运算,我们假设北湖的地面是一维的,每一块宽度都为1,高度是非负整数,那么可以用一个数组来表达一块地面。
例如数组[0,1,0,2,1,0,1,3,2,1,2,1]
可以用来表示下图地面:
图中绿色代表地面部分,蓝色部分代表蓄水部分,蓄水量为 6 。
输入
样例输入有多组。
第一行输入整数 T(1≤T≤100)
表示有 T 组用例;
接下来,对于每组用例,输入一个正整数n(1≤n≤100000)
,表示地面总宽度为 n 。
接下来一行是 n 个数a ,用空格隔开,表示地面高度。(0≤a≤1e9)
输出
对于每个用例输出一行一个数字,表示蓄水总量。
测试样例
2
12
0 1 0 2 1 0 1 3 2 1 2 1
5
5 2 3 2 4
6
5
解答
#include <iostream>
#include <algorithm>
using namespace std;
int main()
{
int T;
cin >> T;
while (T--)
{
int n;
cin >> n;
int arr[100010];
for (int i = 0; i < n; i++)
{
scanf("%d", &arr[i]);
}
long long water = 0;
int leftLargest = 0, rightLargest = 0;
int left[100010];
//left 数组中保存每个元素左边的最大值,left[i],表示数组中第i个元素的左边最大值。
int right[100010];
//right数组中保存每个元素左边的最大值,right[i],表示数组中第i个元素的右边最大值。
for (int i = 0; i < n; i++)
{
leftLargest = max(leftLargest, arr[i]);
left[i] = leftLargest;
}
//先遍历一次找出每个元素左边最大值。
for (int i = n - 1; i >= 0; i--)
{
rightLargest = max(rightLargest, arr[i]);
right[i] = rightLargest;
}
//遍历找到每个元素右边最大值。
for (int i = 0; i < n; i++)
{
water += min(left[i], right[i]) > arr[i] ? min(left[i], right[i]) - arr[i] : 0;
}
cout << water << endl;
}
}