【题目描述】
在一个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
源代码: #include<cstdio> int n,ans(0),i[2001][2001],left[2001][2001],right[2001][2001],f[2001][2001]={0}; int main() { scanf("%d",&n); for (int a=1;a<=n;a++) { scanf("%d",&i[a][1]); left[a][1]=i[a][1]==1?2:1; //边界。 for (int b=2;b<=n;b++) { scanf("%d",&i[a][b]); if (!i[a][b]) //初始化左端。 left[a][b]=left[a][b-1]; else left[a][b]=b+1; } right[a][n]=i[a][n]==1?n-1:n; //边界。 for (int b=n-1;b>0;b--) if (!i[a][b]) //初始化右端。 right[a][b]=right[a][b+1]; else right[a][b]=b-1; } for (int a=1;a<=n;a++) //边界。 f[1][a]=i[1][a]==1?0:1; for (int a=2;a<=n;a++) { for (int b=1;b<=n;b++) if (!i[a][b]) { f[a][b]=f[a-1][b]+1; //悬线法。(Orz 神犇 王知昆) if (!i[a-1][b]) //依据上方的点更新左端右端。 { left[a][b]=left[a][b]>left[a-1][b]?left[a][b]:left[a-1][b]; right[a][b]=right[a][b]<right[a-1][b]?right[a][b]:right[a-1][b]; } int t=(right[a][b]-left[a][b]+1)*f[a][b]; //求最大值。 if (t>ans) ans=t; } } printf("%d",ans); return 0; }
时间: 2024-10-09 15:07:06