当前位置: 首页 > news >正文

专业的上海网站建设郑州网站建设居易国际

专业的上海网站建设,郑州网站建设居易国际,浦东建设环评网站,百度网页版无痕模式最大正方形 题目描述 在一个 n m n\times m nm 的只包含 0 0 0 和 1 1 1 的矩阵里找出一个不包含 0 0 0 的最大正方形,输出边长。 输入格式 输入文件第一行为两个整数 n , m ( 1 ≤ n , m ≤ 100 ) n,m(1\leq n,m\leq 100) n,m(1≤n,m≤100),接…

最大正方形

题目描述

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

输入格式

输入文件第一行为两个整数 n , m ( 1 ≤ n , m ≤ 100 ) n,m(1\leq n,m\leq 100) n,m(1n,m100),接下来 n n n 行,每行 m m m 个数字,用空格隔开, 0 0 0 1 1 1

输出格式

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

样例 #1

样例输入 #1

4 4
0 1 1 1
1 1 1 0
0 1 1 0
1 1 0 1

样例输出 #1

2

题解

这道题AcWing、洛谷和leetCode都有,只是输入还有输出的些微区别,这里只提供洛谷的Python代码,思路是一样的。

这道题其实不难看出来可以用动态规划做,但是我做这道题的时候是有人要求我先用前缀和做一遍了,所以我这里提供两种思路

1、前缀和

这道题前缀和做法其实很简单,就是看我们想要通过求的正方形的前缀和来求该正方形的面积,如果求出来的面积与正方形边长平方相等,那么这个边长的正方形就满足要求

if 通过前缀和求的面积 == 正方形边长 ** 2:return True

在这里插入图片描述
怎么通过前缀和求矩形面积呢?我们可以通过下面公式来计算:
i 2 , j 2 i_2, j_2 i2,j2 为矩形右下角, i 1 , j 1 = i 2 − l e n S q u a r e + 1 , j 2 − l e n S q u a r e + 1 i_1, j_1 = i_2 - lenSquare + 1, j_2 - lenSquare + 1 i1,j1=i2lenSquare+1,j2lenSquare+1 为矩形左上角,那么通过前缀和求矩形面积公式为:
S i z e ( S q u a r e ) = P r e f i x [ i 2 ] [ j 2 ] − P r e f i x [ i 1 − 1 ] [ j 2 ] − P r e f i x [ i 2 ] [ j 1 − 1 ] + P r e f i x [ i 1 − 1 ] [ j 1 − 1 ] Size(Square) =Prefix[i_2][j_2] -Prefix[i_1-1][j_2]-Prefix[i_2][j_1-1] +Prefix[i_1-1][j_1-1] Size(Square)=Prefix[i2][j2]Prefix[i11][j2]Prefix[i2][j11]+Prefix[i11][j11]

下面这张图为上图的前缀和矩阵:
在这里插入图片描述
那么穷举求出每种正方形边长的情况,我们就可以得到可能的正方形边长

欸,别急,直接穷举正方形边长还是慢了,正方形边长是从小到大穷举的,我们可以使用二分来加速对边长的举证:

if mid正方边长满足要求:我们去找是否存在更大的边长满足要求:left = mid + 1
else:mid长度都不符合要求的,直接去找更小的边长了: right = mid - 1

最后得出Python代码(时间复杂度为 O ( N 2 l o g 2 N ) O(N^2log_2N) O(N2log2N)):

def judge(lenEdge, Prefix):global N, Mfor i in range(lenEdge, N+1):for j in range(lenEdge, M+1):if Prefix[i][j] - Prefix[i-lenEdge][j] - Prefix[i][j-lenEdge] + Prefix[i-lenEdge][j-lenEdge] == lenEdge**2:return Trueelse:return FalseN, M = map(int, input().strip().split())
A = [[0 for _ in range(M+1)]]
for i in range(1, N+1):tmp = [0]tmp.extend(map(int, input().strip().split()))A.append(tmp)
Prefix = [[0 for _ in range(M+1)] for _ in range(N+1)]
for i in range(1, N+1):for j in range(1, M+1):Prefix[i][j] = Prefix[i-1][j] + Prefix[i][j-1] - Prefix[i-1][j-1] + A[i][j]
left, right = 0, min(N, M)
ans = 0
while left <= right:mid = (left + right) // 2if judge(mid, Prefix):ans = max(ans, mid)left = mid + 1else:right = mid - 1
print(ans)

在这里插入图片描述

2、动态规划法

动态规划法的想法更容易想到,这里用图来说明一下:

在这里插入图片描述

定义 i , j i,j i,j为正方形的左下角坐标,且 d p [ i ] [ j ] dp[i][j] dp[i][j]存的是该正方形的边长
( 4 , 4 ) (4,4) (4,4)代表的正方形的边长可以从红色、蓝色、绿色,( ( 3 , 3 ) , ( 3 , 4 ) , ( 4 , 3 ) (3,3),(3,4),(4,3) (3,3),(3,4),(4,3))三种颜色的正方形来得出,
可以看出来,黑色框出正方形边长为1+1 = 2,通过多画图推导,得出下面的公式:
d p [ i ] [ j ] = m i n ( d p [ i − 1 ] [ j ] , d p [ i ] [ j − 1 ] , d p [ i − 1 ] [ j − 1 ] ) + 1 dp[i][j] = min(dp[i-1][j],dp[i][j-1],dp[i-1][j-1]) + 1 dp[i][j]=min(dp[i1][j],dp[i][j1],dp[i1][j1])+1

时间复杂度为 O ( N 2 ) O(N^2) O(N2)

N, M = map(int, input().strip().split())
A = [[0 for _ in range(M)]] + [[0] + list(map(int, input().strip().split())) for _ in range(N)]
dp = [[0 for _ in range(M+1)] for _ in range(N+1)]
ans = 0
for i in range(1, N+1):for j in range(1, M+1):if A[i][j] == 1:dp[i][j] = min(dp[i-1][j], dp[i][j-1], dp[i-1][j-1]) + 1ans = max(ans, dp[i][j])
print(ans)

在这里插入图片描述

http://www.yayakq.cn/news/816552/

相关文章:

  • 昆明软讯科技网站建设闸北微信网站建设
  • 福州品牌网站建设公司怎么做网店
  • 我的世界做指令的网站台州网站排名优化
  • 自适应网站做推广做网站需要会哪些编程语言
  • 德宏做网站网站seo入门基础教程
  • 域名做非法网站免费WordPress的产品展示
  • 网站seo成功的营销型网站设计特点
  • 网站跳出率很高会员管理系统设计
  • 移动网站如何优化排名网站管理建设工作报告
  • 网站建设的费用结构包括博州住房和城乡建设局网站
  • 传媒公司注册需要多少钱百度快速优化软件排名
  • 网站编辑属于什么行业百度竞价排名软件
  • 青海省建设厅网站首页wordpress前台很慢
  • 蓬莱网站建设公司青岛网站设计公司联系方式
  • 郑州网站优化汉狮3d建模软件手机版下载
  • 网站最近不收录开发一个小程序游戏要多少钱
  • 网站底部版权怎么做做淘宝优惠券网站
  • 哪里有做网站的素材黄页网络的推广网站有哪些类型
  • 启用中文域名大网站开发微信公众
  • 深圳有做网站的公司有哪些传奇网络游戏
  • 要做网站雨花区师德师风建设专题网站
  • 盘州市城乡建设局网站传媒公司注册需要什么条件
  • 网站有服务器怎么备案公众号开发者模式后自动回复
  • 建网站潞城哪家强?中英双语网站建设
  • 网站注册用户推广如何制作产品网站模板
  • 深圳网站维护wordpress文章勒出
  • 怎么做下载网站吗佛山市建设小学网站
  • 怎建立自己网站做淘宝客数据 导入 wordpress
  • 四川住房和城乡建设厅网站主页wordpress前台登录
  • 开发公司截留占用住宅专项维修资金百度seo按天计费