题目描述

在一个n*m的只包含0和1的矩阵里找出一个不包含0的最大正方形,输出边长。

输入格式

输入文件第一行为两个整数n,m(1<=n,m<=100),接下来n行,每行m个数字,用空格隔开,0或1.

输出格式

一个整数,最大正方形的边长

输入输出样例

输入 #1<button class="copy&#45;btn lfe&#45;form&#45;sz&#45;middle" data&#45;v&#45;370e72e2="" data&#45;v&#45;52f2d52f="" type="button">复制</button>
4 4
0 1 1 1
1 1 1 0
0 1 1 0
1 1 0 1
输出 #1<button class="copy&#45;btn lfe&#45;form&#45;sz&#45;middle" data&#45;v&#45;370e72e2="" data&#45;v&#45;52f2d52f="" type="button">复制</button>
2

 

  思路
  令 f [ i ] [ j ] 为第 a [ i ] [ j ] 个格子上的最大正方形边长。
  显然当 a [ i ] [ j ] == 1 时,状态可能发生变化,转移 f [ i ] [ j ] 应该等于上、左上、左的格子能取到的最小值 + 1 。
 
CODE
 
#include  < bits/stdc++.h >
#define  dbg( x ) cout  <<  #x  <<  " = "  << x  << endl
#define  eps  1 e - 8
#define  pi  acos( - 1.0 )

using  namespace std ;
typedef  long  long LL ;

const  int inf  =  0x 3f3f3f3f ;

template < class T > inline  void  read(& res )
{
     char c ;T flag = 1 ;
     while((c = getchar()) < ' 0 ' ||c > ' 9 ' )if(c == ' - ' )flag =- 1 ;res =c - ' 0 ' ;
     while((c = getchar()) >= ' 0 ' &&c <= ' 9 ' )res =res * 10 +c - ' 0 ' ;res *=flag ;
}

namespace _buff  {
     const  size_t BUFF  =  1  <<  19 ;
     char  ibuf [BUFF ],  *ib  = ibuf ,  *ie  = ibuf ;
     char  getc()  {
         if  (ib  == ie )  {
            ib  = ibuf ;
            ie  = ibuf  +  fread(ibuf ,  1 , BUFF , stdin );
         }
         return ib  == ie  ?  - 1  :  *ib ++ ;
     }
}

int  qread()  {
     using  namespace _buff ;
     int ret  =  0 ;
     bool pos  =  true ;
     char c  =  getc();
     for  (;  (<  ' 0 '  || c  >  ' 9 ' )  && c  !=  ' - ' ; c  =  getc())  {
         assert( ~c );
     }
     if  (==  ' - ' )  {
        pos  =  false ;
        c  =  getc();
     }
     for  (; c  >=  ' 0 '  && c  <=  ' 9 ' ; c  =  getc())  {
        ret  =  (ret  <<  3 )  +  (ret  <<  1 )  +  (^  48 );
     }
     return pos  ? ret  :  -ret ;
}

const  int maxn  =  107 ;

int n , m ;
int  a [maxn ][maxn ];
int  f [maxn ][maxn ];

int  main()
{
     read(n );
     read(m );
     for  (  int i  =  1 ; i  <= n ;  ++)  {
         for  (  int j  =  1 ; j  <= m ;  ++)  {
             read( a [i ][j ]);
         }
     }
     int ans  = INT_MIN ;
     for  (  int i  =  1 ; i  <= n ;  ++)  {
         for  (  int j  =  1 ; j  <= m ;  ++)  {
             if( a [i ][j ])  {
                 f [i ][j ]  =  min(
                     f [-  1 ][-  1 ],  min( f [-  1 ][j ],  f [i ][-  1 ])
                 )  +  1 ;
             }
            ans  =  max( f [i ][j ], ans );
         }
     }
    cout  << ans  << endl ;
     return  0 ;
}