2019牛客暑期多校训练营(第二场)H 题解
https://ac.nowcoder.com/acm/contest/882/H
单调栈来找出某个点的左边和右边第一个高度小于自己的位置,然后记录面积并标记这个矩形。
1 #define bug(x) cout<<#x<<" is "<<x<<endl 2 #define IO std::ios::sync_with_stdio(0) 3 #include <bits/stdc++.h> 4 #define iter ::iterator 5 using namespace std; 6 typedef long long ll; 7 typedef pair<ll,ll>P; 8 typedef pair<P,P>P1; 9 #define mk make_pair 10 #define pb push_back 11 #define se second 12 #define fi first 13 const int N=2e5+5; 14 ll mod=998244353; 15 int n,m; 16 char s[1005][1005]; 17 int h[1005][1005]; 18 map<pair<int,int>,int>mp; 19 int top; 20 int vis[1000005]; 21 struct node{ 22 int v,id; 23 }g[1005]; 24 int l[1005],r[1005]; 25 int main(){ 26 scanf("%d%d",&n,&m); 27 for(int i=1;i<=n;i++){ 28 scanf("%s",s[i]+1); 29 } 30 for(int i=1;i<=n;i++){ 31 for(int j=1;j<=m;j++){ 32 if(s[i][j]=='0')h[i][j]=0; 33 else h[i][j]=h[i-1][j]+1; 34 } 35 } 36 for(int i=1;i<=n;i++){ 37 mp.clear(); 38 top=0; 39 for(int j=1;j<=m;j++){ 40 while(top>0&&g[top].v>=h[i][j]){ 41 top--; 42 } 43 if(top==0){ 44 l[j]=0; 45 } 46 else l[j]=g[top].id; 47 g[++top].v=h[i][j]; 48 g[top].id=j; 49 } 50 top=0; 51 for(int j=m;j>=1;j--){ 52 while(top>0&&g[top].v>=h[i][j]){ 53 top--; 54 } 55 if(top==0){ 56 r[j]=m+1; 57 } 58 else r[j]=g[top].id; 59 g[++top].v=h[i][j]; 60 g[top].id=j; 61 } 62 63 for(int j=1;j<=m;j++){ 64 if(h[i][j]<=0)continue; 65 int k=h[i][j]*(r[j]-l[j]-1); 66 if(!mp[mk(l[j],k)]){ 67 mp[mk(l[j],k)]++; 68 vis[k]++; 69 int k1=h[i][j]*(r[j]-l[j]-2); 70 int k2=(h[i][j]-1)*(r[j]-l[j]-1); 71 if(k1>0)vis[k1]++; 72 if(k2>0)vis[k2]++; 73 } 74 } 75 } 76 int flag=0; 77 for(int i=1e6;i>=1;i--){ 78 while(vis[i]>0){ 79 vis[i]--; 80 if(flag){ 81 printf("%d\n",i); 82 return 0; 83 } 84 flag++; 85 } 86 } 87 printf("0\n"); 88 } 89 /* 90 4 8 91 11111111 92 11111111 93 11111111 94 11111100 95 */