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

每日c/c++题 备战蓝桥杯(洛谷P1387 最大正方形)

洛谷P1387 最大正方形 题解

题目描述

给定一个 n × m n \times m n×m 的01矩阵,要求找出其中全由1组成的最大正方形的边长。

输入格式
第一行两个整数 n , m n, m n,m
接下来 n n n 行每行 m m m 个0或1的数,表示矩阵

输出格式
输出最大正方形的边长

数据范围
1 ≤ n , m ≤ 100 1 \leq n, m \leq 100 1n,m100

解题思路

错误代码分析(DFS解法)

用户提供的DFS代码存在逻辑错误,主要问题如下:

  1. 递归方向错误:DFS应向四个方向扩展,但代码仅向右下扩展,无法覆盖所有可能情况
  2. 状态管理混乱:使用全局变量x1yy记录起点,在递归过程中会被覆盖
  3. 边界判断缺失:未正确处理矩阵边界情况
  4. 时间复杂度高:最坏情况时间复杂度为 O ( n 2 m 2 ) O(n^2m^2) O(n2m2),会超时

正确解法:动态规划(DP)

核心思想
dp[i][j]表示以(i,j)为右下角的最大正方形边长。当matrix[i][j] == 1时:
d p [ i ] [ j ] = min ⁡ ( 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

状态转移解释
当前格子能构成的正方形边长由上方、左方、左上方三个方向的最小值决定,这保证了正方形的完整性。

边界条件

  • i=0j=0时,dp[i][j] = matrix[i][j](第一行/列单独处理)

代码实现(优化版)

#include <bits/stdc++.h>
using namespace std;int main() {int n, m;cin >> n >> m;vector<vector<int>> matrix(n+1, vector<int>(m+1));vector<vector<int>> dp(n+1, vector<int>(m+1, 0));int max_side = 0;// 输入处理(从1开始索引)for(int i = 1; i <= n; ++i) {for(int j = 1; j <= m; ++j) {cin >> matrix[i][j];}}// 动态规划求解for(int i = 1; i <= n; ++i) {for(int j = 1; j <= m; ++j) {if(matrix[i][j] == 1) {dp[i][j] = min({dp[i-1][j], dp[i][j-1], dp[i-1][j-1]}) + 1;max_side = max(max_side, dp[i][j]);}}}cout << max_side << endl;return 0;
}

算法分析

  • 时间复杂度 O ( n m ) O(nm) O(nm),只需遍历矩阵一次
  • 空间复杂度 O ( n m ) O(nm) O(nm),可优化至 O ( m ) O(m) O(m)(滚动数组)
  • 正确性证明:通过数学归纳法可证明状态转移方程的正确性

优化技巧

  1. 空间优化:使用滚动数组将空间复杂度降至 O ( m ) O(m) O(m)
  2. 提前终止:当剩余空间不足以超过当前最大值时提前终止
  3. 输入优化:使用快速读入处理大数据

示例演示

输入样例

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

处理过程

  1. 初始化dp数组全为0
  2. 遍历到(1,2)时,dp[1][2]=1
  3. 遍历到(2,2)时,dp[2][2]=min(0,1,0)+1=1
  4. 遍历到(2,3)时,dp[2][3]=min(1,1,0)+1=1
  5. 最终在(4,4)处得到最大边长3

输出

3

总结

本题是典型的动态规划应用场景,通过状态转移方程巧妙地将二维问题降维处理。相比暴力DFS解法,DP方案在时间和空间效率上都有显著优势。实际编程时需注意:

  1. 矩阵索引从1开始处理更方便
  2. 使用min({a,b,c})语法需要C++11及以上标准
  3. 边界条件需要单独处理

建议掌握该问题的DP解法,并尝试实现空间优化版本以加深理解。

http://www.xdnf.cn/news/5691.html

相关文章:

  • 工业协议跨界实录:零基础玩转PROFINET转EtherCAT主站智能网关
  • 网张实验操作-防火墙+NAT
  • 软考教材重点内容 信息安全工程师 第24章 工控安全需求分析与安全保护工程
  • 如何禁止chrome自动更新
  • 2025年Energy SCI1区TOP,改进雪消融优化算法ISAO+电池健康状态估计,深度解析+性能实测
  • 小白入手搭建本地部署的Dify平台(基于Windows)
  • C++ 跨平台开发挑战与深度解决方案:从架构设计到实战优化
  • 韩国直邮新纪元:Coupang多语言支持覆盖38国市场
  • Spring Data Elasticsearch 中 ElasticsearchOperations 构建查询条件的详解
  • 【Python 基础语法】
  • 直方图特征结合 ** 支持向量机图片分类
  • AD 固定孔及器件的精准定义
  • CVE-2024-26809利用nftables双重释放漏洞获取Root权限
  • 高速边坡监测成本高?自动化如何用精准数据省预算?
  • Oracle集群多副本控制文件异常问题
  • 产品思维30讲-(梁宁)--实战2
  • 分水岭算法:从逻辑学角度看图像分割的智慧
  • Ubuntu20.04 搭建Kubernetes 1.28版本集群
  • C++ 编译报错 undefined reference 找不到引用的问题解决思路
  • vue+element下拉选择器默认选择第一个并根据选择项展示相关数据
  • 瑞派宠物医生:借腔镜影像妙技,筑牢宠物生命防线
  • 4.MySQL全量、增量备份与恢复
  • 构造二叉树
  • STM32的TIMx中Prescaler和ClockDivision的区别
  • AI与IoT携手,精准农业未来已来
  • Nacos源码—8.Nacos升级gRPC分析六
  • 2025年5月12日第一轮
  • 最大子数组和
  • Ubuntu虚拟机文件系统扩容
  • 通过Windows操作系统双因素认证实现工业设备安全运维:安当SLA