题目大意:给定一个黑白两色的矩阵,求最大的黑白相间的子正方形和子矩阵
将奇数位置的点反色,然后就是求纯色的最大子正方形和子矩阵
将矩阵一层层剖分,每层上方是一段类似于▆▃▇▂▉的东西,用单调栈跑出每个点向左向右能拓展到的最大距离,更新答案即可
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define M 2020 using namespace std; int m,n,ans1,ans2; int map[M][M],a[M]; void Calculate() { static int stack[M],top; static int left[M],right[M]; int i;top=0; for(i=1;i<=n+1;i++) { while( top && a[i]<a[stack[top]] ) { right[stack[top]]=i; stack[top--]=0; } stack[++top]=i; } top=0; for(i=n;~i;i--) { while( top && a[i]<a[stack[top]] ) { left[stack[top]]=i; stack[top--]=0; } stack[++top]=i; } for(i=1;i<=n;i++) { int len=right[i]-left[i]-1; ans1=max(ans1,min(len,a[i])*min(len,a[i]) ); ans2=max(ans2,len*a[i]); } } int main() { int i,j; cin>>m>>n; for(i=1;i<=m;i++) for(j=1;j<=n;j++) { scanf("%d",&map[i][j]); if(i+j&1) map[i][j]^=1; } for(i=1;i<=m;i++) { for(j=1;j<=n;j++) a[j]=(map[i][j]?0:a[j]+1); Calculate(); } memset(a,0,sizeof a); for(i=1;i<=m;i++) for(j=1;j<=n;j++) map[i][j]^=1; for(i=1;i<=m;i++) { for(j=1;j<=n;j++) a[j]=(map[i][j]?0:a[j]+1); Calculate(); } cout<<ans1<<endl<<ans2<<endl; return 0; }
时间: 2024-11-08 20:16:49