bzoj 1057: [ZJOI2007]棋盘制作
2016-06-20
这就是一个最大全0子矩阵 和 最大全0子正方形 不过把0改成01间隔,话说我把一个m打成n还过了一半
1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<cstdlib> 5 #include<algorithm> 6 #include<queue> 7 #define M 2009 8 #define ll long long 9 #define Mo 12345678 10 using namespace std; 11 ll read() 12 { 13 char ch=getchar(); 14 ll x=0,f=1; 15 for(;ch<'0'||ch>'9';ch=getchar()) 16 if(ch=='-') 17 f=-1; 18 for(;ch>='0'&&ch<='9';ch=getchar()) 19 x=x*10+ch-'0'; 20 return x*f; 21 } 22 int n,m,a[M][M],f[M][M],H[M],ans=1,L[M],R[M]; 23 int main() 24 { 25 n=read(); 26 m=read(); 27 for(int i=1;i<=n;i++) 28 for(int j=1;j<=m;j++) 29 a[i][j]=read(); 30 for(int i=1;i<=n;i++) 31 { 32 int h=0; 33 for(int j=1;j<=m;j++) 34 { 35 if(a[i][j]==a[i][j-1]) 36 h=1; 37 else 38 h++; 39 if(a[i][j]==a[i-1][j]) 40 H[j]=1; 41 else 42 H[j]++; 43 if(a[i][j]==a[i-1][j-1]) 44 f[i][j]=min(h,min(f[i-1][j-1]+1,H[j])); 45 else 46 f[i][j]=1; 47 ans=max(ans,f[i][j]); 48 } 49 } 50 printf("%d\n",ans*ans); 51 ans=0; 52 memset(H,0,sizeof(H)); 53 L[1]=1; 54 R[m]=m; 55 for(int i=1;i<=n;i++) 56 { 57 for(int j=1;j<=m;j++) 58 if(a[i][j]==a[i-1][j]) 59 H[j]=1; 60 else 61 H[j]++; 62 for(int j=2;j<=m;j++) 63 if(a[i][j-1]!=a[i][j]&&H[j-1]>=H[j]) 64 L[j]=L[j-1]; 65 else 66 L[j]=j; 67 for(int j=1;j<=m;j++) 68 for(;a[i][L[j]-1]!=a[i][L[j]]&&H[L[j]-1]>=H[j];L[j]=L[L[j]-1]); 69 for(int j=m-1;j;j--) 70 if(a[i][j+1]!=a[i][j]&&H[j+1]>=H[j]) 71 R[j]=R[j+1]; 72 else 73 R[j]=j; 74 for(int j=m;j;j--) 75 for(;a[i][R[j]+1]!=a[i][R[j]]&&H[R[j]+1]>=H[j];R[j]=R[R[j]+1]); 76 for(int j=1;j<=m;j++) 77 ans=max((R[j]-L[j]+1)*H[j],ans); 78 } 79 printf("%d\n",ans); 80 return 0; 81 }