样例:
2 12 0 1 0 2 1 0 1 3 2 1 2 1 5 5 2 3 2 4
解题思路
cin会t,需要快读或者打scanf 并且记得改longlong
这个题时限要求紧,需要o(n)过。
根据题意我们要求两个高点中间装了多少水,这样的话我们就可以从左到右、从右到左遍历一遍找到每个点两边的高点,之后如果这个点的水能被两边搂住,我们就加上这些水。
代码:
#include <cstdio>
#include <cstring>
#include<iostream>
using namespace std;
int a[100010];
int r[100010];
int main(){
int t;
ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
cin>>t;
while(t--){
int n;
memset(r,0,n*4+10);//清空数组初始化
cin>>n;
long long ans=0;
int ma=0;
for(int i=1;i<=n;i++){
cin>>a[i];
}
for(int i=n;i>=1;i--){
r[i]=max(a[i],r[i+1]);//找到右边的最大值
}
for(int i=1;i<=n;i++){
if(a[i]>ma)ma=a[i];//左边的最大值
if(ma>r[i])ma=r[i];//左右最大值的最小值
if(r[i]>=ma)//有了上一步这个好像没啥用了?
ans+=ma-a[i];//相当于竖着一条一条考虑,这一竖条的水就是他能装的水
}
cout<<ans<<endl;
}
}