GESP2025年9月认证C++四级真题与解析(编程题1(排兵布阵))

一、先看原题


二、题目解析

1、《在方格王国里找最大草坪》

(1)想象这样一个世界 🏰:

  • 这是一块方格王国

  • 每个格子:

    • 1= 🌱 草地(可以建房)

    • 0= 🌋 火山(不能建)

我们的任务是:

🏡 找一块全是草地的最大长方形区域
给国王建一个大房子!


2、例如这样一张“地图” 🗺️

一个4 × 5 的地图

行\列 1 2 3 4 5 1 1 1 0 1 1 2 1 1 0 1 1 3 1 1 1 1 1 4 0 1 1 1 0

3、最笨但最安全的办法是什么?🤔

🤷‍♂️不知道哪里最大,那就全部试一遍!

这就是我们首先想的方法:

👉枚举所有可能的矩形


4、如何“枚举所有矩形”?🧠

(1)一个矩形,需要4 个信息

左上角:(x1, y1) 右下角:(x2, y2)

(2)如果两个矩形的左上角相同,右下角也相同,这就是相同的矩形。

换句话说,如果两个矩形,只要左上角与右上角有一个不相同,就是不同的矩形


(3)所以我们枚举所有矩形:

1️⃣ 选左上角
2️⃣ 选右下角
3️⃣ 根据左上角,与右上角,枚举这个矩形内部的所有点,看看有不是全部都是1

4️⃣ 如果全部都是1,就与前面枚举的矩形面积比大小,更新max

👉 这就是使用最朴素枚举方法来解决这个问题


5、参考程序:

#include <iostream> using namespace std; int a[25][25]; int n, m; int main() { cin >> n >> m; // 读入矩阵 for (int i = 1; i <= n; i++) { for (int j = 1; j <= m; j++) { cin >> a[i][j]; } } int ans = 0; // ① 枚举左上角行 for (int x1 = 1; x1 <= n; x1++) { // ② 枚举左上角列 for (int y1 = 1; y1 <= m; y1++) { // ③ 枚举右下角行 for (int x2 = x1; x2 <= n; x2++) { // ④ 枚举右下角列 for (int y2 = y1; y2 <= m; y2++) { bool ok = true; // ⑤ 枚举矩形内部行 for (int i = x1; i <= x2; i++) { // ⑥ 枚举矩形内部列 for (int j = y1; j <= y2; j++) { if (a[i][j] == 0) { ok = false; } } } // 如果这个矩形全是 1 if (ok) { int area = (x2 - x1 + 1) * (y2 - y1 + 1); ans = max(ans, area); } } } } } cout << ans << endl; return 0; }

6、时间复杂度符合吗?

(1)先说结论

✅ 本题数据范围,n,m < 12,是可以通过的


(2)矩阵大小是:

n × m

那么

循环次数
左上角n × m
右下角n × m
检查内部n × m

(3)👉 总复杂度大约是:

O(n² · m² · n · m) = O(n³ · m³)

三、高阶提升:

🧠如何对朴素枚举程序进行优化呢?

(一)、使用二维前缀预处理,可以减少矩形合法性计算时间!

二维前缀和不能减少“枚举矩形的次数”,
但可以把“检查一个矩形是否合法”的复杂度
从 O(面积) 降到 O(1)


1、算法思路

原始朴素暴力(问题在哪)

  • 每次:再扫一遍矩形内部,看是不是全 1

👉慢在“反复扫描矩形内部”


2、用二维前缀和之后

1️⃣预处理一个前缀和数组sum
2️⃣ 枚举所有矩形
3️⃣O(1) 判断矩形里 1 的个数


3、参考程序:

#include <iostream> using namespace std; int a[20][20]; int sum[20][20]; int main() { int n, m; cin >> n >> m; // 读入矩阵 for (int i = 1; i <= n; i++) { for (int j = 1; j <= m; j++) { cin >> a[i][j]; } } // 1️⃣ 计算二维前缀和 for (int i = 1; i <= n; i++) { for (int j = 1; j <= m; j++) { sum[i][j] = sum[i-1][j] + sum[i][j-1] - sum[i-1][j-1] + a[i][j]; } } int ans = 0; // 2️⃣ 枚举所有矩形 for (int x1 = 1; x1 <= n; x1++) { for (int x2 = x1; x2 <= n; x2++) { for (int y1 = 1; y1 <= m; y1++) { for (int y2 = y1; y2 <= m; y2++) { // 用前缀和 O(1) 计算矩形内 1 的个数 int ones = sum[x2][y2] - sum[x1-1][y2] - sum[x2][y1-1] + sum[x1-1][y1-1]; int area = (x2 - x1 + 1) * (y2 - y1 + 1); // 如果全是 1,更新答案 if (ones == area) { ans = max(ans, area); } } } } } cout << ans << endl; return 0; }

4、时间复杂度

部分复杂度
前缀和预处理O(nm)
枚举矩形O(n²m²)
矩形合法性判断O(1)

👉总复杂度:O(n²m²)


(二)、固定上下边 + 压成一维(状态压缩)


1、算法一句话总览🎯

固定矩形的“上边”和“下边”,
把二维矩阵压缩成一维数组,
再在一维数组中找“最长连续 1 段”。


2、为什么这样能减少循环?

(1)原来(4 重循环)在枚举什么?

上边 + 下边 + 左边 + 右边

👉 你是在枚举“矩形本身”


(2)现在(固定上下边)枚举什么?

上边 + 下边 + 一次横向扫描

👉 是在枚举“高度”,横向找宽度


(3)本质变化

❌ 枚举矩形
✅ 枚举“高度 + 连续宽度”


3、核心思想拆解

1️⃣ 固定上下边

for (int top = 1; top <= n; top++) { for (int bottom = top; bottom <= n; bottom++) { ... } }

👉 确定了矩形的高度

height = bottom - top + 1;

2️⃣ 对每一列,判断“这一整列能不能用”

对某一列j

  • 如果top ~ bottom这一列全是 1
    👉 这一列是1

  • 只要有一个0
    👉 这一列是0

这样就得到一个一维 0/1 数组


3️⃣ 一维问题变成什么?

在 0/1 数组中,找最长连续的 1

我们已经非常熟悉了:

if (col[j] == 1) cnt++; else cnt = 0;

4️⃣ 面积怎么计算?

面积 = 连续列数 * 高度

4、【固定上下边 + 压成一维】完整参考程序

#include <iostream> using namespace std; int a[20][20]; int main() { int n, m; cin >> n >> m; // 读入矩阵 for (int i = 1; i <= n; i++) { for (int j = 1; j <= m; j++) { cin >> a[i][j]; } } int ans = 0; // 1️⃣ 固定上边 for (int top = 1; top <= n; top++) { // col[j] 表示:当前 top 到 bottom 之间, // 第 j 列是否全是 1 int col[20] = {0}; // 2️⃣ 枚举下边 for (int bottom = top; bottom <= n; bottom++) { // 更新每一列是否仍然“可用” for (int j = 1; j <= m; j++) { if (bottom == top) { // 第一行,直接赋值 col[j] = a[bottom][j]; } else { // 只要出现 0,这一列就废了 col[j] = col[j] && a[bottom][j]; } } // 当前矩形高度 int height = bottom - top + 1; // 3️⃣ 在 col[] 中找最长连续 1 int cnt = 0; for (int j = 1; j <= m; j++) { if (col[j] == 1) { cnt++; ans = max(ans, cnt * height); } else { cnt = 0; } } } } cout << ans << endl; return 0; }

5、时间复杂度分析

部分复杂度
枚举 top, bottomO(n²)
每次扫描列O(m)

👉总复杂度:O(n² · m)
👉 比前缀和的O(n² · m²)明显更快


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/1191375.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

高频去耦电容配置方法:操作指南(含实例)

高频去耦电容怎么配&#xff1f;老工程师的实战经验全在这里&#xff08;附FPGA真实案例&#xff09;你有没有遇到过这样的问题&#xff1a;电路板焊好了&#xff0c;上电却莫名其妙地死机&#xff1b;FPGA配置失败&#xff0c;DDR跑不通&#xff0c;示波器一测电源满屏“毛刺”…

超详细版SystemVerilog随机测试生成技术深度剖析

掌握随机&#xff0c;突破边界&#xff1a;SystemVerilog激励生成的工程艺术你有没有遇到过这样的场景&#xff1f;一个SoC模块有十几个配置寄存器、几十种操作模式&#xff0c;组合起来的功能路径成千上万。用定向测试一个个“点兵点将”&#xff0c;不仅耗时如沙漏&#xff0…

28.C++进阶:map和set封装|insert|迭代器|[]

封装红⿊树实现mymap和myset 源码及框架分析 SGI-STL30版本源代码&#xff0c;map和set的源代码在map/set/stl_map.h/stl_set.h/stl_tree.h等⼏个头⽂件中。 map和set的实现结构框架核⼼部分截取出来如下&#xff1a; // set #ifndef __SGI_STL_INTERNAL_TREE_H #include &…

大数据时代,Power BI 成为数据洞察的关键工具

大数据时代&#xff0c;Power BI 成为数据洞察的关键工具&#xff1a;从零到一的实战指南 1. 标题 (Title) 以下是 5 个吸引人的标题选项&#xff0c;涵盖核心关键词“大数据”“Power BI”“数据洞察”&#xff1a; 《大数据浪潮下&#xff0c;Power BI 如何让你的数据“会…

vivado2021.1安装教程:满足工控高可靠性要求的方法

如何在工控场景下构建稳定可靠的 Vivado 2021.1 开发环境 工业控制系统的开发&#xff0c;从来不只是写代码和烧录 FPGA。当你面对的是运行在高温车间、连续工作十年不能宕机的 PLC 控制器&#xff0c;或是驱动精密机械臂的运动控制系统时&#xff0c;每一个环节都必须经得起时…

计算机毕业设计springboot易耗品管理系统 基于SpringBoot的企业低值易耗品智能管理平台 SpringBoot驱动的办公耗材全流程管控系统

计算机毕业设计springboot易耗品管理系统pwg9y9un &#xff08;配套有源码 程序 mysql数据库 论文&#xff09; 本套源码可以在文本联xi,先看具体系统功能演示视频领取&#xff0c;可分享源码参考。在数字化办公与精益生产双重推动下&#xff0c;小到一支笔、大到一桶墨&#x…

基于MAX3232的RS232接口引脚定义调试技巧

从MCU到PC&#xff1a;一文吃透MAX3232串口通信的引脚连接与调试实战你有没有遇到过这样的场景&#xff1f;单片机代码写得没问题&#xff0c;UART初始化也正确&#xff0c;但就是收不到PC发来的数据&#xff1b;或者串口助手显示乱码、偶尔丢包&#xff0c;查了一圈软件逻辑却…

计算机毕业设计springboot飞机票预定系统 基于SpringBoot的航空客运订票平台设计与实现 融合Vue+SpringBoot的在线航班座位预约系统

计算机毕业设计springboot飞机票预定系统yr7f205a &#xff08;配套有源码 程序 mysql数据库 论文&#xff09; 本套源码可以在文本联xi,先看具体系统功能演示视频领取&#xff0c;可分享源码参考。当“说走就走”成为年轻人出行的默认节奏&#xff0c;传统柜台与电话订票早已跟…

Pspice安装教程:从下载到运行的全面讲解

从零开始搭建Pspice仿真环境&#xff1a;一次搞定安装、配置与首个电路验证 你是不是也曾在准备做课程设计或自学模拟电路时&#xff0c;被“ Pspice怎么装不上&#xff1f; ”这个问题卡住过&#xff1f; 明明下载了安装包&#xff0c;点击 setup.exe 却弹出一堆错误&am…

教学思考(3)

一、 背景与政策梳理(国家层面) 汇报首先梳理了人工智能教育在国家政策层面的演进脉络,强调了从“模块化”到“体系化”的转变。课程标准演进:高中(2017/2020修订版):人工智能作为必修一的章节内容及选择性必修…

计算机毕业设计springboot乡镇人口信息管理系统 基于SpringBoot的乡镇居民信息综合管理平台 面向基层治理的SpringBoot人口大数据服务系统

计算机毕业设计springboot乡镇人口信息管理系统tjvav0jl &#xff08;配套有源码 程序 mysql数据库 论文&#xff09; 本套源码可以在文本联xi,先看具体系统功能演示视频领取&#xff0c;可分享源码参考。在城乡融合不断提速的今天&#xff0c;乡镇级人口数据呈爆炸式增长&…

打造智能化 ECS 故障分析 Agent:从创建到实战

前言 在微服务架构中,ECS 服务故障排查往往需要在多个 AWS 控制台之间切换,查看日志、指标、事件,耗时且容易遗漏关键信息。本文将介绍如何使用 Kiro CLI 创建一个专业的 ECS 故障分析 Agent,实现一键自动化诊断。 一、Agent 设计理念 1.1 核心目标 自动化:输入服务名称…

数字频率计设计:FPGA开发环境配置指南

从零开始搭建数字频率计&#xff1a;FPGA开发环境实战配置全记录 你有没有遇到过这样的场景&#xff1f;手头有一个高频信号需要测量&#xff0c;万用表不够准&#xff0c;示波器又太贵&#xff0c;而市面上的频率计要么精度不够、要么功能单一。于是你决定自己动手做一个——…

Altium原理图与FPGA引脚规划协同设计实践

从原理图到FPGA引脚&#xff1a;如何在Altium中实现高效协同设计你有没有遇到过这样的场景&#xff1f;FPGA工程师说&#xff1a;“这个DDR信号我只能放Bank 15&#xff0c;不然时序不收敛。”而PCB工程师回&#xff1a;“可你在Bank 15用了1.8V&#xff0c;但我们的DDR3要求1.…

emuelec固件升级注意事项:安全更新操作指南

emuelec固件升级实战指南&#xff1a;从备份到恢复的全链路避坑手册 你有没有经历过这样的时刻&#xff1f;兴致勃勃地下载了新版emuelec固件&#xff0c;想着终于能用上最新的PS2模拟优化和蓝牙手柄支持&#xff0c;结果一通操作后——屏幕黑了、WiFi连不上、存档全没了。重启…

组合逻辑电路设计入门必看:基本概念与实例解析

组合逻辑电路设计入门必看&#xff1a;从门电路到功能模块的实战解析你有没有遇到过这样的情况&#xff1a;明明代码写得没问题&#xff0c;烧录进FPGA后却发现输出“飘忽不定”&#xff1f;或者仿真时一切正常&#xff0c;上板测试却频频出错&#xff1f;很多初学者在学习数字…

SkyWalking 接口超时监控告警完整指南

目录 一、SkyWalking 简介 二、安装部署 三、告警配置 四、管理维护 五、最佳实践 六、故障排查 一、SkyWalking 简介 1.1 什么是 SkyWalking SkyWalking 是一个开源的 APM(应用性能监控)系统,专为微服务、云原生和容器化架构设计。 核心功能: 📊 分布式追踪:完整的调…

图解说明三极管开关电路:基础结构与信号流向

三极管开关电路全解析&#xff1a;从零搞懂驱动设计的底层逻辑你有没有遇到过这种情况&#xff1f;想用单片机控制一个继电器&#xff0c;结果发现IO口输出电流太小&#xff0c;直接带不动&#xff1b;或者调试LED调光时&#xff0c;亮度总不稳定&#xff0c;怀疑是驱动出了问题…

汇编语言全接触-99.检测内存中的 Soft-Ice

概述&#xff1a;检测内存中的 Soft-Ice 又一法&#xff0c;不过这次用的是在全部内存搜索 Soft-Ice 的特征码来实现的。汇编编程示例&#xff1a;; 加密方法: 检测 s-ice; 用 scas,cmps 等指令, s-ice 无法用; bpm 等断点检测到, 因此可用比较关键…

Prim 最小生成树算法(MST)

Prim算法是贪婪算法&#xff0c;类似于Kruskal算法。该算法始终从单个节点出发&#xff0c;经过多个相邻节点&#xff0c;以探索沿途所有连接的边。 该算法从一个空生成树开始。 其理念是维持两组顶点。第一组包含已包含在MST中的顶点&#xff0c;另一组包含尚未包含的顶点。 …