news 2026/4/15 17:44:45

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

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
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²)明显更快


版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/11 23:56:14

语言模型推理能力的认知风格影响因素分析

语言模型推理能力的认知风格影响因素分析 关键词:语言模型、推理能力、认知风格、影响因素、分析 摘要:本文聚焦于语言模型推理能力的认知风格影响因素进行深入分析。首先介绍了研究的背景、目的、预期读者和文档结构等内容。接着阐述了语言模型、推理能力和认知风格的核心概…

作者头像 李华
网站建设 2026/4/11 0:16:19

有没有推荐的汽车自动化生产系统或智能解决方案?

在汽车制造这个行当里&#xff0c;自动化正在悄悄经历一场本质的蜕变。早年间&#xff0c;我们谈论的还只是机械臂按固定程序焊接、喷涂、搬运——机器固然高效&#xff0c;但说到底&#xff0c;只是听令行事的“工具”。而如今&#xff0c;情况不一样了。随着AI、物联网和数字…

作者头像 李华
网站建设 2026/4/11 8:14:17

AI法律文书准确性测试方法论

一、风险背景与技术挑战 当前法律AI工具在生成起诉状、合同等文书时存在三类核心风险&#xff1a;虚构法条&#xff08;如评测中出现的错误法条引用&#xff09;、逻辑矛盾&#xff08;如将"双方约定"误用为"甲方必须"的强制性表述&#xff09;及过时条款…

作者头像 李华
网站建设 2026/3/27 18:29:52

跨境电商“防关联”实战指南:把风险挡在账号之外

跨境平台的风控越来越“聪明”&#xff1a;同一批设备、网络、支付、收货、资料、操作习惯之间&#xff0c;只要出现可被平台归因的“共同点”&#xff0c;就可能触发关联审查&#xff0c;轻则限流、二审&#xff0c;重则直接封号、资金冻结。防关联不是“玄学”&#xff0c;核…

作者头像 李华
网站建设 2026/4/2 11:41:36

计算机毕业设计springboot基于web的流浪动物信息管理系统 基于SpringBoot的流浪宠物救助与领养平台 Web端流浪猫狗信息追踪及领养服务系统

计算机毕业设计springboot基于web的流浪动物信息管理系统285i7752 &#xff08;配套有源码 程序 mysql数据库 论文&#xff09; 本套源码可以在文本联xi,先看具体系统功能演示视频领取&#xff0c;可分享源码参考。当城市化的脚步越来越快&#xff0c;街巷里出现的流浪动物也在…

作者头像 李华
网站建设 2026/4/13 16:23:47

孤能子视角:“1+1=2“

我的问题(前两个千问回答&#xff0c;第三个信兄回答):1.看看"112"人类认知演化。2.演化中都遇到哪些困难&#xff0c;最后又如何解决&#xff1f;3.以上是千问对"112"人类认知演化史的解读。EIS又会给出怎样的洞察呢&#xff0c;又会如何判断人工智能学习…

作者头像 李华