欢迎光临
我们一直在努力

GESP C++2025年6月四级考试编程题(第一题 画布裁剪)详细解析


🌈 一、故事开场:小画家小 A 的烦恼

1、小 A 是个小画家,他画了一幅画在一个大大的画布上。

画布是一个:

  • 高 n 行

  • 宽 m 列


2、就像一个 n × m 的字符方格地图。

比如:

…..
.>_<.
…..

但是呢……

小 A 发现画的主体只有中间那一小块,四周全是空白。


3、他的要求:

“我要把画布裁剪一下,只保留我要的那一块!”


4、于是我们:

  • 从第 x1 行 到 第 x2 行

  • 从第 y1 列 到 第 y2 列

把这一块剪下来打印出来。


🧠 二、先理解题目本质

1、其实这题在考什么?

👉 本质就是:

从二维字符矩阵中,截取一个子矩阵并输出


2、是不是很像:

  • 取数组的一部分?

  • 二维数组的局部输出?


3、这题核心就是:

✅ 二维数组的范围控制


📦 三、我们一步一步拆解思考过程


1、🎯 第一步:怎么存画布?

(1)题目说:

接下来 n 行,每行一个长度为 m 的字符串。

所以我们可以这样存:

char s[105][105];


(2)或者用 string:

string s[105];


(3)为什么是 105?

因为题目最大 n,m ≤ 100
多给一点空间,安全!


2、🎯 第二步:如何理解“裁剪”?

(1)假设:

x1 = 2
x2 = 3
y1 = 2
y2 = 4


(2)意思是:

  • 行:只看第2行到第3行

  • 列:只看第2列到第4列


(3)就像从一个大地图里:

📍 切出一个小矩形


3、✂ 裁剪本质是什么?

我们只需要:

for (int i = x1; i <= x2; i++)
for (int j = y1; j <= y2; j++)
输出 s[i][j]

是不是超级清楚?


🧠 四、关键算法思考全过程

1、很多同学看到题目会慌:

“这是不是要用什么高级算法?”


2、不要谎!我们可以逐个考点分析:


1️⃣ 有排序吗?

没有


2️⃣ 有搜索吗?

没有


3️⃣ 有递推吗?

没有


4️⃣ 有复杂数学吗?

没有


3、那它到底考什么?

👉 二维数组读入 + 双重循环控制范围


🎯 五、完整思考路径总结

我们做编写程序时,思路这样走:


1、🪜 第一步:读入参数

cin >> n >> m;
cin >> x1 >> x2 >> y1 >> y2;


2、🪜 第二步:读入画布

for (int i = 1; i <= n; i++)
cin >> s[i];


3、🪜 第三步:控制行范围

for (int i = x1; i <= x2; i++)


4、🪜 第四步:控制列范围

for (int j = y1; j <= y2; j++)


5、🪜 第五步:输出并换行

每输出完一行要换行!


💻 六、标准代码

1、参考代码:

#include <iostream>
using namespace std;

int main()
{
int n, m;
cin >> n >> m;

int x1, x2, y1, y2;
cin >> x1 >> x2 >> y1 >> y2;

string s[105];

for(int i = 1; i <= n; i++)
{
cin >> s[i];
}

for(int i = x1; i <= x2; i++)
{
for(int j = y1; j <= y2; j++)
{
cout << s[i][j-1];
}
cout << endl;
}

return 0;
}


⚠ 注意:

  • string 下标从 0 开始

  • 题目行列是从 1 开始

所以列要写 j-1


2、参考代码:

#include <cstdio>
using namespace std;
const int N = 105;
int n, m;
char s[N][N];
int x1, x2, y1, y2;
int main() {
scanf("%d%d", &n, &m);
scanf("%d%d%d%d", &x1, &x2, &y1, &y2);
for (int i = 1; i <= n; i++)
scanf("%s", s[i] + 1);
for (int i = x1; i <= x2; i++) {
s[i][y2 + 1] = 0;
printf("%s\\n", s[i] + y1);
}
return 0;
}


⏱ 七、时间复杂度分析

1、假设:

  • n 最大 100

  • m 最大 100


2、最多输出:

100 × 100 = 10000 次

时间复杂度:

O(n × m)


🌟 八、这题考点

能力是否考察
二维数组
双重循环
下标控制
细节严谨
复杂算法

🚨 九、最容易错的地方

❌ 错误1:忘记 j-1

会导致:

  • 输出错位

  • 或 RE 错误


❌ 错误2:循环写成 < 而不是 <=

少输出一行或一列。


❌ 错误3:行列顺序写反

记住:

先控制行
再控制列


🎉 十、这题的等级定位

1、这题属于:

四级里的“送分题”


2、它考察:

  • 你是否会基本数组操作

  • 是否能认真控制边界。


🏁 最后总结一句话

🎨《画布裁剪》的本质是:

在二维字符矩阵中,按给定范围输出子矩阵。

核心能力:

  • 二维数组理解

  • 下标细节控制

  • 双重循环结构


预测模拟题:

🎯《升级版裁剪(自动寻找非空白区域)》


🌈 一、题目升级版

1、小 A 又画了一幅画。

这次他没有告诉你:

  • 从第几行到第几行

  • 从第几列到第几列


2、他只说了一句话:

“帮我把四周的空白都裁掉,只留下画的主体!”


3、这下麻烦了……

我们要 自动找出画的主体在哪儿!


🧠 二、题目真正考什么?

升级题其实在考:

✅ 二维数组遍历
✅ 找最小矩形包围区域
✅ 边界更新思维

这才是四级考生应该有的水平了!


🎨 三、什么叫“非空白区域”?

1、假设画布是:

…..
..#..
..#..
…..


2、这里:

. 是空白
# 是画的内容


3、我们要裁剪成:

##
##


4、其实就是找出:

  • 最上面的非空白行

  • 最下面的非空白行

  • 最左边的非空白列

  • 最右边的非空白列


🧩 四、核心算法思考过程

我们一步一步思考:


1、🪜 第一步:我们要找什么?

我们需要 4 个变量:

top = 最小行号
bottom = 最大行号
left = 最小列号
right = 最大列号


2、🪜 第二步:怎么找到它们?

我们遍历整个画布!

for 每一行
for 每一列
如果不是空白
更新边界


3、🔥 关键算法思想:动态更新边界

假设当前坐标是 (i, j),发现是画的一部分:

我们就:

top = min(top, i);
bottom = max(bottom, i);
left = min(left, j);
right = max(right, j);


🧠 五、完整思考流程


🎯 1️⃣ 初始化

一开始我们不知道主体在哪。

所以:

top = n
bottom = 1
left = m
right = 1


🎯 2️⃣ 扫描全图

一格一格找。

只要发现不是 . 的字符:

就更新边界。


🎯 3️⃣ 最后得到一个矩形

就是:

(top, left) 到 (bottom, right)


🎯 4️⃣ 输出这个矩形

和原题一样:

双重循环输出,或者格式化输出。


💻 六、完整代码

#include <iostream>
using namespace std;

int main()
{
int n, m;
cin >> n >> m;

string s[105];

for(int i = 0; i < n; i++)
{
cin >> s[i];
}

int top = n, bottom = -1;
int left = m, right = -1;

// 扫描全图
for(int i = 0; i < n; i++)
{
for(int j = 0; j < m; j++)
{
if(s[i][j] != '.') // 非空白
{
if(i < top) top = i;
if(i > bottom) bottom = i;
if(j < left) left = j;
if(j > right) right = j;
}
}
}

// 输出裁剪结果
for(int i = top; i <= bottom; i++)
{
for(int j = left; j <= right; j++)
{
cout << s[i][j];
}
cout << endl;
}

return 0;
}


⏱ 七、时间复杂度分析

1、扫描一次全图:

O(n × m)


2、输出最多也是:

O(n × m)


3、总复杂度:

O(n × m)

非常安全。


🚀 八、算法思想升华

1、这题其实是:

找二维数组中满足条件的最小包围矩形


2、这种思想以后会用在:

  • 图像处理

  • 游戏地图裁剪

  • 连通块问题

  • DFS 扫描


🌟 九、常见错误

❌ 忘记初始化为极值
❌ 行列搞反
❌ 没处理“全空白”的情况

如果全是 . 呢?

那就什么都不输出,或者按照考试说明输出。


🎓 十、和原题基础版的区别

基础版升级版
给定范围 自动寻找范围
直接输出 先扫描再输出
简单循环 带边界更新

🏁 最终总结一句话

🎯 升级版裁剪的核心是:

在二维数组中,扫描所有元素,动态维护最小包围矩形。


赞(0)
未经允许不得转载:171主机测评 » GESP C++2025年6月四级考试编程题(第一题 画布裁剪)详细解析
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址