2019.4.7 提高B组 T1 nssl-1304 最大正方形

版权声明:虽然本蒟蒻很菜,但各位dalao转载请注明出处谢谢。 https://blog.csdn.net/xuxiayang/article/details/89154483

D e s c r p t i o n Descrption

给定一个 n × n n\times n 的01矩阵,要求求出其中最大的全部由1构成的正方形的面积。

数据范围:
n 1 0 3 n\leq 10^3


S o l u t i o n Solution

f [ i ] [ j ] f[i][j] 表示以 ( i , j ) (i,j) 为右下角的正方形的边长

我们可以通过边长从1到2的情况类比大的情况

显然,当边长为1转移到边长为2时,需要满足上方,左方,左上方三个角都必须是正方形,而我们如何获知这个信息呢,由方程的定义即可得到,得到一个比较简陋的方程

f [ i ] [ j ] = f [ i 1 ] [ j ] + 1 a [ i 1 ] [ j ] = = 1   a n d   a [ i 1 ] [ j 1 ] = = 1   a n d   a [ i ] [ j 1 ] = = 1   a n d   a [ i ] [ j ] = = 1 f[i][j]=f[i-1][j]+1 |a[i-1][j]==1\ and\ a[i-1][j-1]==1\ and\ a[i][j-1]==1\ and\ a[i][j]==1

这就是1转移到2的方程了

但是,其实后面的判断条件可以省略掉,我们取最小值即可

f [ i ] [ j ] = m i n { f [ i 1 ] [ j ] , f [ i ] [ j 1 ] , f [ i 1 ] [ j 1 ] } + 1 a [ i ] [ j ] = = 1 f[i][j]=min\{f[i-1][j],f[i][j-1],f[i-1][j-1]\}+1|a[i][j]==1

可以发现,这条方程代入到 > 2 边长>2 的情况也是成立的

对此我们可以有两种理解方法

第一种,我们可以把正方形的边长当作同时压缩,这样其的形状恰好可以构成 = 2 边长=2 的情况

第二种,我们可以用类似与二维前缀和的理解方法,一个大的正方形,可以看成上方小的正方形,左边小的正方形加上自己组成

问题到这里已经得到解决,时间复杂度 O ( n 2 ) O(n^2)


C o d e Code

#include<cstdio>
#include<algorithm>
#define r(i,a,b) for(int i=a;i<=b;i++)
using namespace std;char a[1001][1001];int f[1001][1001],n,ans;
int main()
{
    scanf("%d\n",&n);
    r(i,1,n) {r(j,1,n) a[i][j]=getchar();getchar();}
    r(i,1,n)
     r(j,1,n)
      if(a[i][j]=='1')
       f[i][j]=min(min(f[i-1][j],f[i][j-1]),f[i-1][j-1])+1;
    r(i,1,n) r(j,1,n) ans=max(ans,f[i][j]*f[i][j]);
    printf("%d",ans);
}

猜你喜欢

转载自blog.csdn.net/xuxiayang/article/details/89154483
今日推荐