题目描述:
2478 小b接水
小b将n个宽度相同的积木顺序摆在一起,如下图所示。
现在她告诉你每个积木的高度(可能为0)。
她想知道如果她从高处倒下一杯水,最多有多少单位的水能被积木接住?
假设每个积木的宽度都为1。
上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表示的高度图,在这种情况下,最多可以接 6 个单位的水(蓝色部分表示水)。
收起
输入
第一行一个正整数n,其中0<n≤50000; 第二行n个数表示从左到右每个积木的高度,以空格隔开,每个数不超过10000。输出
一个数,表示最多可以接的水量输入样例
12 0 1 0 2 1 0 1 3 2 1 2 1输出样例
6
思路:
乍一看挺像是单调栈的题目,但考虑半天也没想出怎么做,首先我们知道,
单调栈是找一个值前面或者后面比他大/小的最远位置,
且中间不能出现破环单调
性的元素。(可以出现)单调栈好像也可以,求出所有“低处”拐点,每一个拐点L,R之间区域
对应一个水坑。然后求对应体积即可。PS:这样单调栈的L,R求出的水坑是多个水坑,因为其可能跨过“上界”拐点。
另一种巧妙的思路是,逐位考虑每一个柱子,如果该柱子上方有水,
那其高度一定==min(左最大值,右边最大值)-a[i]。然后叠加即可。
实现代码(递推最大值):
#include<bits/stdc++.h>
#define LL long long
using namespace std;
const int N=2e5+100;
int a[N];
int Left[N],Right[N];
int main()
{
int n;
while(cin>>n)
{
LL ans=0;
for(int i=1;i<=n;i++)cin>>a[i];
for(int i=1;i<=n;i++)Left[i]=max(Left[i-1],a[i]);
for(int i=n;i>=1;i--)Right[i]=max(Right[i+1],a[i]);
for(int i=1;i<=n;i++)
ans+=min(Left[i],Right[i])-a[i];
cout<<ans<<endl;
}
return 0;
}
实现代码一:
单调栈错误思路。。。
The end;