[ZJOI2007]棋盘制作
题目分析
求一个黑白相间的最大矩形面积。
算法分析
乍一看很像求最大矩形面积但求不这么好求,所以需要一个转化,将隔的斜行白变黑,黑变白,再求最大的黑色或白色矩形(因为你不知道变完之后哪个多)
然后按每列横着拓展按单调栈求最大面积就行了。
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N=2200;
int a[N][N],h0[N][N],h1[N][N],n,m,ans1,ans2,d[N],s[N],top;
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
scanf("%d",&a[i][j]);
if(i%2==j%2)a[i][j]=1-a[i][j];
}
for(int j=m;j>=1;j--){
if(a[i][j]==1)h0[i][j]=h0[i][j+1]+1;
else h0[i][j]=0;
if(a[i][j]==0)h1[i][j]=h1[i][j+1]+1;
else h1[i][j]=0;
}
}
ans1=0;
ans2=0;
for(int j=1;j<=m;j++){
d[1]=h0[1][j];
s[1]=1;
top=1;
for(int i=2;i<=n+1;i++){
int tt=0;
while(top>0&&d[top]>=h0[i][j]){
tt+=s[top];
ans1=max(ans1,tt*d[top]);
ans2=max(ans2,min(tt,d[top])*min(tt,d[top]));
--top;
}
top++;
tt++;
d[top]=h0[i][j];
s[top]=tt;
}
}
for(int j=1;j<=m;j++){
d[1]=h1[1][j];
s[1]=1;
top=1;
for(int i=2;i<=n+1;i++){
int tt=0;
while(top>0&&d[top]>=h1[i][j]){
tt+=s[top];
ans1=max(ans1,tt*d[top]);
ans2=max(ans2,min(tt,d[top])*min(tt,d[top]));
--top;
}
top++;
tt++;
d[top]=h1[i][j];
s[top]=tt;
}
}
printf("%d\n%d",ans2,ans1);
return 0;
}