链接:戳这里
思路:首先分析出只有U型才可以盛水,所以我们用单调队列维护,数组中存的是从高到低的积木,当碰到一块积木比队列中最后一块cnt的积木高的话,意味着存在U型,所以通过cnt-1,cnt,a[i]算出U型面积,算完之后意味着这一部分就填平了,移出队列,然后判断到第cnt块积木比ai高为止,如果一直都比当前的ai低的话,并且队列中第1块都比ai低的话,说明这个队列就需要清空了,这里一直wa
代码:
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<string> #include<vector> #include <ctime> #include<queue> #include<set> #include<map> #include<stack> #include<iomanip> #include<cmath> #define mst(ss,b) memset((ss),(b),sizeof(ss)) #define maxn 0x3f3f3f3f #define MAX 1000100 ///#pragma comment(linker, "/STACK:102400000,102400000") typedef long long ll; typedef unsigned long long ull; #define INF (1ll<<60)-1 using namespace std; int T,n; int a[1000100]; struct node{ int v,id; }s[1000100]; int main(){ scanf("%d",&T); while(T--){ scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d",&a[i]); int t=1; while(a[t+1]>=a[t] && t<n) t++; if(t==n){ cout<<0<<endl; continue; } t=1; while(a[t+1]<=a[t] && t<n) t++; if(t==n){ cout<<0<<endl; continue; } t=1; while(a[t+1]>=a[t] && t<n) t++; int cnt=0; s[++cnt].v=a[t]; s[cnt].id=t; s[++cnt].v=a[t+1]; s[cnt].id=t+1; ll ans=0; for(int i=t+2;i<=n;i++){ if(a[i]<=s[cnt].v){ s[++cnt].v=a[i]; s[cnt].id=i; } else { while(a[i]>s[cnt].v && cnt>1){ int x=min(a[i],s[cnt-1].v)-s[cnt].v; int l=i-s[cnt-1].id-1; ans+=(ll)x*l; cnt--; } if(cnt==1 && a[i]>s[1].v) cnt--; s[++cnt].v=a[i]; s[cnt].id=i; } } printf("%lld\n",ans); } return 0; } /* 10 3 2 1 3 5 2 1 1 1 2 5 4 2 2 1 4 4 4 3 5 6 */