最大正方形子矩阵

【题目描述】

在一个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;
}
原文地址:https://www.cnblogs.com/Ackermann/p/5289242.html