题目描述

题目链接:https://www.luogu.org/problemnew/show/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

算法解析:

来源:http://www.cnblogs.com/CXSheng/p/7801313.html

本题也可以参考洛谷题解

动态规划,求什么设什么。

设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] = min(maxSize[i-1][j-1]+1,leftNum1[i][j]+1,upNum1[i][j]+1)

注意边界情况即可。

 #include<stdio.h>
#define MAXN 100
#define MAXM 100
int array[MAXN+][MAXM+]={};
int maxSize[MAXN+][MAXM+]={};
int leftNum1[MAXN+][MAXM+]={};
int upNum1[MAXN+][MAXM+]={};
int n,m;
int Figure(int tempN,int tempM)
{
if(tempN-==||tempM-==||array[tempN-][tempM-]==)
return ;
int min=maxSize[tempN-][tempM-]+;
if(leftNum1[tempN][tempM]+<min)
min=leftNum1[tempN][tempM]+;
if(upNum1[tempN][tempM]+<min)
min=upNum1[tempN][tempM]+;
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=;
for(i=;i<=n;i++)
for(j=;j<=m;j++)
scanf("%d",&array[i][j]);
for(i=;i<=n;i++)
for(j=;j<=m;j++)
{
if(j==||array[i][j]==)
leftNum1[i][j]=;
else
{
if(array[i][j-]==)
leftNum1[i][j]=;
else
leftNum1[i][j]=leftNum1[i][j-]+;
} if(i==||array[i][j]==)
upNum1[i][j]=;
else
{
if(array[i-][j]==)
upNum1[i][j]=;
else
upNum1[i][j]=upNum1[i-][j]+;
}
}
for(i=;i<=n;i++)
for(j=;j<=m;j++)
{
maxSize[i][j]=Figure(i,j);
if(maxSize[i][j]>maxans)
maxans=maxSize[i][j];
}
tPrint();
printf("%d\n",maxans);
return ;
}

类似参考题目:

洛谷P1736 创意吃鱼法  题解

洛谷P1387 最大正方形的更多相关文章

  1. 洛谷 p1387最大正方形

    洛谷 p1387最大正方形 题目描述 在一个n*m的只包含0和1的矩阵里找出一个不包含0的最大正方形,输出边长. 输入格式 输入文件第一行为两个整数n,m(1<=n,m<=100),接下来 ...

  2. 洛谷 P1387 最大正方形 【dp】(经典)

    题目链接:https://www.luogu.org/problemnew/show/P1387 题目描述 在一个n*m的只包含0和1的矩阵里找出一个不包含0的最大正方形,输出边长. 输入格式: 输入 ...

  3. 洛谷 P1387 最大正方形 Label:奇怪的解法

    题目描述 在一个n*m的只包含0和1的矩阵里找出一个不包含0的最大正方形,输出边长. 输入输出格式 输入格式: 输入文件第一行为两个整数n,m(1<=n,m<=100),接下来n行,每行m ...

  4. 洛谷 [P1387] 最大正方形

    本题非常有趣. (n^6) 枚举四个端点,每次遍历矩阵求解. (n^4) 先处理前缀和,枚举四个端点,每次比较前缀和和正方形面积. (n^3) 枚举左上方端点,在枚举边长,前缀和优化 (n^2logn ...

  5. 洛谷P1387最大正方形(dp,前缀和)

    题目描述 在一个n*m的只包含0和1的矩阵里找出一个不包含0的最大正方形,输出边长. 输入输出格式 输入格式: 输入文件第一行为两个整数n,m(1<=n,m<=100),接下来n行,每行m ...

  6. (Java实现) 洛谷 P1387 最大正方形

    题目描述 在一个n*m的只包含0和1的矩阵里找出一个不包含0的最大正方形,输出边长. 输入输出格式 输入格式: 输入文件第一行为两个整数n,m(1<=n,m<=100),接下来n行,每行m ...

  7. [洛谷1681]最大正方形II

    思路:对于矩阵中的每一个元素,处理出它能扩展到的上边界$up$.左边界$left$,DP得出以该元素为右下角的最大正方形.状态转移方程:$f_{i,j}=min(f_{i-1,j-1},up_{i,j ...

  8. 洛谷P1681 最大正方形II

    P1681 最大正方形II 题目背景 忙完了学校的事,v神终于可以做他的“正事”:陪女朋友散步.一天,他和女朋友走着走着,不知不觉就来到 了一个千里无烟的地方.v神正要往回走,如发现了一块牌子,牌子上 ...

  9. 洛谷 P2701 [USACO5.3]巨大的牛棚Big Barn Label:二维数组前缀和 你够了 这次我用DP

    题目背景 (USACO 5.3.4) 题目描述 农夫约翰想要在他的正方形农场上建造一座正方形大牛棚.他讨厌在他的农场中砍树,想找一个能够让他在空旷无树的地方修建牛棚的地方.我们假定,他的农场划分成 N ...

随机推荐

  1. window.parent window.top window.parent.location.pathname 没权限

    跨域问题啊,如果只是测试的话,放到服务器去测试,本地的(http://localhost/)就算是在同一个文件下,都会被认为跨域的.如果不需要支持低版本IE浏览,可以使用postMessage处理这个 ...

  2. aspnet_regiis -i VS 20XX 的开发人员命令提示符

    1,VS 2010 Setting environment x86 tools. D:\Program Files\Microsoft Visual Studio 10.0\VC>aspnet_ ...

  3. python Genarator函数

    Generator函数的定义与普通函数的定义没有什么区别,只是在函数体内使用yield生成数据项即可.Generator函数可以被for循环遍历,而且可以通过next()方法获得yield生成的 数据 ...

  4. 第二十八章 springboot + zipkin(brave定制-AsyncHttpClient)

    brave本身没有对AsyncHttpClient提供类似于brave-okhttp的ClientRequestInterceptor和ClientResponseInterceptor,所以需要我们 ...

  5. .Net(c#)打印--多页打印

    如果要实现多页打印,就要使用PrintPageEventArgs类的HasMorePages属性. 我们对之前的代码作如下变更:      增加PrintDocument的BeginPrint和End ...

  6. Android -- Canvas java.lang.UnsupportedOperationException

    干货 java.lang.UnsupportedOperationException at android.view.GLES20Canvas.clipPath(GLES20Canvas.java:2 ...

  7. Android利用RecognizerIntent识别语音并简单实现打电话动作

    关于Android利用RecognizerIntent识别语音并简单实现打电话,详细看实现代码例如以下: package com.example.recognizerintentactivity; i ...

  8. 用 CSS 实现元素垂直居中,有哪些好的方案?

    1.不知道自己高度和父容器高度的情况下, 利用绝对定位只需要以下三行: parentElement{ position:relative; } childElement{ position: abso ...

  9. .NET Framework System.Array.Sort 数组类,加深对 IComparer、IComparable 以及泛型委托、匿名方法、Lambda 表达式的理解

    本文内容 自定义类 Array.Sort 参考资料 System.Array.Sort 有很多对集合的操作,比如排序,查找,克隆等等,你可以利用这个类加深对 IComparer.IComparable ...

  10. Springboot项目启动报错,提示Cannot determine embedded database driver class for database type NONE

    我在springboot项目里面引入了数据库的配置: <dependency> <groupId>org.mybatis.spring.boot</groupId> ...