小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
题解 : 对于每一个位置, 计算出它左边最高和右边最高(用两个数组保存) , 扫描一边,当遇到 凹的时候,也就是当前高度比左边低,
并且比右边低时, 用左右最高的最低高度减去当前位置高度 .
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std ;
const int MAX = 50010 ;
int a[MAX] ;
int Left[MAX] ;
int Right[MAX] ;
// 枚举每个位置,遇到凹 时 , 取左右高度最小减去该位置高度
int main(){
int n ;
cin >>n ;
for(int i = 1 ; i<=n ; i++ ){
scanf("%d",&a[i]);
}
Left[1] = a[1] ;
Right[n] = a[n] ;
int ans = 0 ;
// 从左到右扫描左边最大
for(int i = 2 ; i<n ; i++ ) {
Left[i] = max(Left[i-1],a[i]) ;
}
// 从右边扫描右边最大
for(int i = n-1 ; i>1 ; i--) {
Right[i] = max(Right[i+1],a[i]) ;
}
for(int i = 2 ; i<n; i ++ ) {
if(a[i] < Left[i] && a[i] < Right[i]){ // 当到达一个位置
// 这个位置比左边右边都低时 ,
int mid = min(Left[i] ,Right[i]) ;
ans +=(mid-a[i]) ;
}
}
cout<<ans ;
return 0 ;
}