洛谷 P1318 积水面积(单调栈)
传送门
解题思路
其实很简单的一个单调栈就可以解决的题,题解里的做法都写的很麻烦。
建立一个强制不为空的单调递减栈,然后运用扫描线的思想可以快速求出面积。
强制不为空是为了保证最左端一定要有柱子。单调递减是因为受到影响某个区域能否存储水的是左面和右面最高的柱子中的最小值。
可以借助下图进行理解:
分开区域进行计算即可。
AC代码
#include<cstdio>
#include<iostream>
#include<cstring>
#include<iomanip>
#include<cmath>
#include<algorithm>
#include<stack>
using namespace std;
const int maxn=1e4+5;
int n,a[maxn],ans;
stack<int> q;
int main(){
ios::sync_with_stdio(false);
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
for(int i=2;i<=n-1;i++){//单调递减栈,且不为空。
while(!q.empty()&&a[q.top()]<a[i]){
int last=q.top();
q.pop();
if(!q.empty()) ans+=(min(a[q.top()],a[i])-a[last])*(i-q.top()-1);
}
q.push(i);
}
cout<<ans;
return 0;
}