I. 天气の子 [ Problem 4866 ] [ Discussion ]
Description
一位拥有操作天气超能力的少女说道:“呐,现在开始就要放晴了哦~”
于是倾盆大雨停止了,天空放晴了……
她发现一些路边的石柱接住了一些雨水,她很好奇,这些石柱接住了多少雨水呢?如下图所示,这是n 个石柱的侧视图,请计算按此排列的石柱接住了多少雨水(黑色为石柱,蓝色为雨水)。
Input
第一行,一个非负整数n(0≤n≤3×104 ),表示有n 个石柱。
第二行,n 个非负整数组成的序列,表示石柱的高度height[i](0≤height[i]≤105,0≤i<n)。
Output
输出只有一行,包含一个非负整数num 表示石柱可以接住的雨水量。
Samples
Input Copy
12
0 1 0 2 1 0 1 3 2 1 2 1
Output
6
Source
2020年烟大校赛
这题比较有意思哈,一开始我想到的是把这个不规则图形给补齐咯,然后再求规则图形的面积。然后,发现,啊,这咋求,求不出来呀,直接没了。然后这题也是比较靠后,比赛的时候并没有写出来。
晚上到宿舍,欢佬一波指点,马上去把他写了。随即AC;
解题思路:对于每一个点,找到在它左侧的最大值,再找一个他右侧的最大值,两者取min再与当前点的高度取差计入答案即可。
上代码:
#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
int a[30010], Left[30010],Right[30010];
int main()
{
int n;
scanf("%d", &n);
for (int i = 1;i <= n;i++)
{
scanf("%d", &a[i]);
}
int max1 = 0;
for (int i = 1;i <= n;i++)
{
max1 = max(max1, a[i]);
Left[i] = max1;
}
max1 = 0;
for (int i = n;i >= 1;i--)
{
max1 = max(max1, a[i]);
Right[i] = max1;
}
int ans = 0;
for (int i = 1;i <= n;i++)
{
ans += min(Right[i], Left[i]) - a[i];
}
cout << ans << endl;
return 0;
}