【20171107】Luogu P1387 最大正方形

题目描述

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

输入输出格式

输入格式:

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

输出格式:

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

输入输出样例

输入样例#1:复制
4 4
0 1 1 1
1 1 1 0
0 1 1 0
1 1 0 1
输出样例#1:复制
2

求什么设什么。
maxSize[i][j] = a[i][j]为右下角的最大正方形边长,

maxSize[i][j] = k代表着a[i][j]左上方k*k区域内的数字都是1

起初我想,如果a[i][j]1,那么就可以把maxSize[i-1][j-1]代表的一大片矩形的边长扩大1.

maxSize[i][j]=

  0 a[i-1][j-1]==0 or 边界;

  maxSize[i-1][j-1]+1 , a[i-1][j-1]!=0

 

但是!这是片面的,因为我忽略了a[i][j]正上方和正左方是否存在0的情况。

如图:


假设我们要求maxSize[i][j]对应着最右下角的红点,

浅蓝色的圈是maxSize[i-1][j-1]对结果的影响;

橙色的圈是a[i][j]正上方连续的1对结果的影响;

绿色的圈是a[i][j]正左方连续的1对结果的影响;

总图如下:

去三个值中最小的,记入maxSize[i][j]

综上可知,更新设定:

当a[i][j]为1时:

maxSize[i][j] = a[i][j]为右下角的最大正方形边长,

LeftNum1[i][j] = a[i][j](不包括)正左边连续1的个数,

UpNum1[i][j] = a[i][j](不包括)正上方边连续1的个数,

于是maxSize[i][j] = minmaxSize[i-1][j-1]+1,leftNum1[i][j]+1,upNum1[i][j]+1

注意边界情况即可。


//begin at 20:55
#include<stdio.h>
#define MAXN 100
#define MAXM 100
int array[MAXN+1][MAXM+1]={0};
int maxSize[MAXN+1][MAXM+1]={0};
int leftNum1[MAXN+1][MAXM+1]={0};
int upNum1[MAXN+1][MAXM+1]={0};
int n,m;
int Figure(int tempN,int tempM)
{
    if(tempN-1==0||tempM-1==0||array[tempN-1][tempM-1]==0)
        return 1;
    int min=maxSize[tempN-1][tempM-1]+1;
    if(leftNum1[tempN][tempM]+1<min)
        min=leftNum1[tempN][tempM]+1;
    if(upNum1[tempN][tempM]+1<min)
        min=upNum1[tempN][tempM]+1;
    return min;
}
void tPrint()
{
/*    int i,j;
    printf("\n");
    for(i=1;i<=n;i++)
    {
        for(j=1;j<=m;j++)
            //printf("%d ",[i][j]);
            printf("%d ",upNum1[i][j]);//==============
        printf("\n");
    }
    printf("\n");*/
}
int main()
{
    int i,j;
    scanf("%d%d",&n,&m);
    int maxans=0;
    for(i=1;i<=n;i++)
        for(j=1;j<=m;j++)
            scanf("%d",&array[i][j]);
    for(i=1;i<=n;i++)
        for(j=1;j<=m;j++)
        {
            if(j==1||array[i][j]==0)
                leftNum1[i][j]=0;
            else
            {
                if(array[i][j-1]==0)
                    leftNum1[i][j]=0;
                else
                    leftNum1[i][j]=leftNum1[i][j-1]+1;
            }
            
            if(i==1||array[i][j]==0)
                upNum1[i][j]=0;
            else
            {
                if(array[i-1][j]==0)
                    upNum1[i][j]=0;
                else
                    upNum1[i][j]=upNum1[i-1][j]+1;
            }
        }
    for(i=1;i<=n;i++)
        for(j=1;j<=m;j++)
        {
            maxSize[i][j]=Figure(i,j);
            if(maxSize[i][j]>maxans)
                maxans=maxSize[i][j];
        }
    tPrint();
    printf("%d\n",maxans);
    return 0;
}
//end at 21:23

 

posted @ 2017-11-07 21:53  Cxsheng  阅读(150)  评论(0编辑  收藏  举报