【题目描述】
在一个01矩阵中,包含有很多的正方形子矩阵,现在要求出这个01矩阵中,最大的正方形子矩阵,使得这个正方形子矩阵中的某一条对角线上的值全是1,其余的全是0。
【输入描述】
第一行有两个整数n和m(1 <= n,m <= 1000)。接下来的n行,每行有m个0或1的数字。每两个数字之间用空格隔开。
【输出描述】
输出一个整数,表示满足条件的最大正方形子矩阵的边长。
【样例输入】
4 6
0 1 0 1 0 0
0 0 1 0 1 0
1 1 0 0 0 1
0 1 1 0 1 0
【样例输出】
3
源代码: #include<cstdio> int m,n,ans(0),i[1001][1001]={0},f1[1001][1001]={0},f2[1001][1001]={0},h1[1001][1001]={0},h2[1001][1001]={0}; int main() { scanf("%d%d",&m,&n); for (int a=1;a<=m;a++) for (int b=1;b<=n;b++) { scanf("%d",&i[a][b]); h2[a][b]=h1[a][b]=i[a][b]; //初始化“和之数组”。 } for (int a=1;a<=n;a++) h1[1][a]+=h1[1][a-1]; for (int a=n;a>0;a--) h2[1][a]+=h2[1][a+1]; for (int a=1;a<=n;a++) f2[1][a]=f1[1][a]=i[1][a]; //对第一行进行预处理。 for (int a=2;a<=m;a++) for (int b=1;b<=n;b++) //对后方进行处理。 { h1[a][b]+=h1[a-1][b]+h1[a][b-1]-h1[a-1][b-1]; //对区域和进行处理。 if (i[a-1][b-1]) f1[a][b]=f1[a-1][b-1]+1; if (f1[a][b]==(h1[a][b]-h1[a][b-f1[a][b]]-h1[a-f1[a][b]][b]+h1[a-f1[a][b]][b-f1[a][b]])&&f1[a][b]>ans) //若1の数量=区域和,则符合题意。 ans=f1[a][b]; } for (int a=2;a<=m;a++) //同理于上。 for (int b=n;b>0;b--) //注意,此处应为倒序。 { h2[a][b]+=h2[a-1][b]+h2[a][b+1]-h2[a-1][b+1]; //注意左对角线处理与右对角线处理的区别。 if (i[a-1][b+1]) f2[a][b]=f2[a-1][b+1]+1; if (f2[a][b]==(h2[a][b]-h2[a][b+f2[a][b]]-h2[a-f2[a][b]][b]+h2[a-f2[a][b]][b+f2[a][b]])&&f2[a][b]>ans) ans=f2[a][b]; } printf("%d",ans); return 0; }