在一个0,1方阵中找出其中最大的全0子矩阵,所谓最大是指O的个数最多。
输入文件第一行为整数N,其中1<=N<=2000,为方阵的大小,紧接着N行每行均有N个0或1,相邻两数间严格用一个空格隔开。
输出文件仅一行包含一个整数表示要求的最大的全零子矩阵中零的个数。
5
0 1 0 1 0
0 0 0 0 0
0 0 0 0 1
1 0 0 0 0
0 1 0 0 0
9
悬线法算法2模板题。可以加滚动数组来优化
【代码1】
#include<iostream> #include<cstring> #include<cstdio> #define N 2005 using namespace std; int n,maxl,maxr,l[N][N],r[N][N],h[N][N],ans,a[N][N]; int main(){ scanf("%d",&n); for (int i=1;i<=n;++i) for (int j=1;j<=n;++j) scanf("%d",&a[i][j]); for (int i=1;i<=n;++i) r[0][i]=n; for (int i=1;i<=n;++i){ maxl=1,maxr=n; for (int j=1;j<=n;++j) if (a[i][j]){ maxl=j+1; h[i][j]=l[i][j]=0; } else{ h[i][j]=h[i-1][j]+1; l[i][j]=max(maxl,l[i-1][j]); } for (int j=n;j>=1;--j) if (a[i][j]){ maxr=j-1; r[i][j]=n; } else{ r[i][j]=min(maxr,r[i-1][j]); ans=max(ans,(r[i][j]-l[i][j]+1)*h[i][j]); } } printf("%d\n",ans); }
#include<iostream> #include<cstdio> #include<cstring> using namespace std; #define N 2005 int h[N],l[N],r[N],ans=0,a[N][N],maxl,maxr,n; int main(){ scanf("%d",&n); for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) scanf("%d",&a[i][j]); for(int i=1;i<=n;i++) r[i]=n; for(int i=1;i<=n;i++){ maxl=1,maxr=n; for(int j=1;j<=n;j++) if(a[i][j]){ maxl=j+1; h[j]=l[j]=0; } else{ h[j]++; l[j]=max(l[j],maxl); } for(int j=n;j>=1;j--) if(a[i][j]){ maxr=j-1; r[j]=n; } else{ r[j]=min(r[j],maxr); ans=max(ans,h[j]*(r[j]-l[j]+1)); } } printf("%d",ans); }