很多同学在通过了 GESP 一级和二级的考试后,会产生一种错觉:C++ 编程就是用 if-else 和 for 循环解决各种数学计算问题。然而,当你翻开 GESP三级 的试卷时,你会发现一个全新的世界。
从三级开始,考试的核心不再仅仅是基础语法的堆砌,而是正式引入了数据结构(一维和二维数组、字符串)以及基础的算法(排序、查找)。面对庞大的数据,如何存储?如何高效地处理?这就是三级考试要考察的核心能力。
今天,我们将从历年 GESP三级 的真题库中,挑选出极具代表性的题型进行一次深度的“真题精讲”。我们将跳出单一的答案,通过对比不同的解题思路,带你体会算法优化的魅力。
一、 排序算法的对决:冒泡排序 vs 选择排序
在 GESP三级 的大纲中,明确要求掌握冒泡排序和选择排序。真题中不仅会考察代码实现,还会考察对这两种排序过程的理解。
真题重现:成绩排名
题目大意:给定 N 个学生的成绩,要求将成绩从高到低进行排序并输出。如果成绩相同,则保持输入时的相对顺序。
解法一:冒泡排序(Bubble Sort)
冒泡排序的核心思想是相邻元素两两比较,如果顺序错误就交换。这种方法的优点是稳定,能够完美满足题目中“成绩相同保持相对顺序”的要求。
#include <iostream>
using namespace std;
int main() {
int n;
int scores[1000];
cin >> n;
for(int i = 0; i < n; i++) {
cin >> scores[i];
}
// 冒泡排序核心逻辑
for(int i = 0; i < n - 1; i++) {
for(int j = 0; j < n - 1 - i; j++) {
if(scores[j] < scores[j+1]) { // 降序排列
int temp = scores[j];
scores[j] = scores[j+1];
scores[j+1] = temp;
}
}
}
for(int i = 0; i < n; i++) {
cout << scores[i] << " ";
}
return 0;
}解法二:选择排序(Selection Sort)
选择排序的思想是每次从待排序的数据中选出最大(或最小)的一个元素,存放在序列的起始位置。
// 选择排序核心逻辑替换
for(int i = 0; i < n - 1; i++) {
int max_idx = i;
for(int j = i + 1; j < n; j++) {
if(scores[j] > scores[max_idx]) {
max_idx = j;
}
}
// 交换
if(max_idx != i) {
int temp = scores[i];
scores[i] = scores[max_idx];
scores[max_idx] = temp;
}
}思路对比:
从代码量上看,两者相差无几。但在实际执行中,冒泡排序可能会进行大量的交换操作,而选择排序每轮最多只交换一次。不过需要注意的是,基础的选择排序是不稳定的,如果在更复杂的结构体排序中,可能会打乱相同分数的原始顺序。掌握这两种排序的差异,是三级选择题的常考考点。
二、 空间换时间的魔法:频次统计
频次统计(又称桶排序思想或哈希思想初步)是 GESP三级 中极高频的考点。它考察的是学生能否跳出嵌套循环,利用数组下标的特性来解决问题。
真题重现:寻找出现次数最多的数
题目大意:输入 N 个介于 0 到 100 之间的整数,找出其中出现次数最多的数字。
常规解法:暴力枚举(易超时)
很多初学者的第一反应是:拿每一个数去和数组里的所有数比较,数一数有几个。
int max_count = 0;
int most_frequent = -1;
for(int i = 0; i < n; i++) {
int count = 0;
for(int j = 0; j < n; j++) {
if(arr[i] == arr[j]) count++;
}
if(count > max_count) {
max_count = count;
most_frequent = arr[i];
}
}这种解法使用了双重循环,如果 N 很大,程序运行会非常缓慢。
高阶解法:频次数组(核心考点)
既然数字的范围是 0 到 100,我们完全可以创建一个大小为 101 的数组,把数字本身作为数组的下标,数组里存储的则是该数字出现的次数。
#include <iostream>
using namespace std;
int main() {
int n, num;
int count[105] = {0}; // 初始化频次数组全为0
cin >> n;
for(int i = 0; i < n; i++) {
cin >> num;
count[num]++; // 核心:以数值为下标,统计次数
}
int max_count = 0;
int most_frequent = -1;
for(int i = 0; i <= 100; i++) {
if(count[i] > max_count) {
max_count = count[i];
most_frequent = i;
}
}
cout << most_frequent << endl;
return 0;
}通过这种方式,我们只用了一层循环就解决了问题,这就是典型的“空间换时间”的算法思维。
在练习这类数组题目时,同学们最常遇到的问题就是“数组越界”(Segmentation Fault),这类报错在传统的编译器中通常是一串难以看懂的英文。如果你在使用 AdaCpp 平台进行日常练习,它的 AI 智能助手能够自动捕获 GCC 编译器的报错,将其翻译成中文,并直接在你的代码中指出哪一行的数组下标超出了定义的范围,给出具体的修复建议。这对于刚接触数组的三级考生来说,能节省大量独自查错的时间。
三、 字符串的灵活处理:C风格与string类
GESP三级大纲中同时包含了字符数组(C风格字符串)和 string 类基本操作。真题中经常要求对字符串进行遍历、替换或统计。
真题重现:简单的密码解密
题目大意:给定一个仅包含大写字母的字符串,将其中的每个字母向后移动3位(如 A 变成 D,X 变成 A),输出解密后的字符串。
解题思路拆解:
这道题的核心在于处理字母的循环越界问题(即 Z 后面要回到 A)。我们可以使用 ASCII 码的特性来进行计算。
#include <iostream>
#include <string>
using namespace std;
int main() {
string s;
cin >> s;
for(int i = 0; i < s.length(); i++) {
// 判断是否需要循环回A
if(s[i] >= 'X' && s[i] <= 'Z') {
s[i] = s[i] - 26 + 3;
} else {
s[i] = s[i] + 3;
}
}
cout << s << endl;
return 0;
}在这里,我们使用了 string 类。相比于 C 风格的字符数组,string 类自带的 .length() 方法让遍历变得非常安全且直观。三级考试中,熟练掌握 string 的读入、遍历和拼接,是拿高分的关键。
四、 降维打击:前缀和初步应用
在三级大纲中,提到了“前缀和初步”。这是一种极其优雅的数组应用,专门用来解决“频繁查询某个区间内数字之和”的问题。
真题重现:区间求和
题目大意:给定一个长度为 N 的数组,随后有 M 次询问。每次询问给出两个位置 L 和 R,要求输出从第 L 个元素到第 R 个元素的总和。
常规解法:
每次询问都写一个 for 循环,从 L 遍历到 R 进行累加。如果 M 非常大,程序会重复计算很多次,导致超时。
前缀和解法:
我们可以提前计算好一个“前缀和数组” sum,其中 sum[i] 表示原数组前 i 个元素的总和。那么查询 L 到 R 的区间和,只需要计算 sum[R] - sum[L-1] 即可。
#include <iostream>
using namespace std;
int main() {
int n, m;
int arr[1005];
int sum[1005] = {0};
cin >> n;
for(int i = 1; i <= n; i++) {
cin >> arr[i];
sum[i] = sum[i-1] + arr[i]; // 构建前缀和数组
}
cin >> m;
for(int i = 0; i < m; i++) {
int l, r;
cin >> l >> r;
// O(1) 时间复杂度得出结果
cout << sum[r] - sum[l-1] << endl;
}
return 0;
}看,原本需要循环 M * (R-L) 次的操作,被我们简化成了 M 次简单的减法。这就是算法优化的绝对力量。
总结与备考建议
通过以上真题精讲,我们可以清晰地看到:GESP三级不仅仅是写出能运行的代码,更是要求你写出“聪明”的代码。你需要在大脑中建立起数组作为数据容器的概念,理解字符串的本质,并掌握用空间换时间、预处理等基础算法思维。
纸上得来终觉浅,绝知此事要躬行。所有的算法逻辑,都必须通过大量的敲击键盘和真题训练才能内化。
如果你正在寻找一个高效的备考环境,推荐体验一下 AdaCpp 在线学习平台。你不需要在电脑上折腾复杂的环境配置,打开浏览器就能直接写代码。平台内置了 78 套 GESP 历年真题(覆盖2023年9月至2025年3月),并配有即时评测的 OJ 系统,写完代码一键提交,对错立刻知晓。

对于需要系统学习的同学,AdaCpp 的 L2 课程(C++进阶提高)完全对标 GESP 3-4 级的考试大纲,将上述的数组、字符串、排序、前缀和等知识点进行了细致的切片教学。配合 AI 智能助手的实时答疑,即使遇到再难的算法逻辑,也能得到适合你当前年龄段的详尽解释。
距离下一次 GESP 考试还有时间,现在就开始你的算法进阶之旅吧!

感谢阅读!如果你觉得这篇文章对你的备考有帮助,请点击右下角的“在看”和“赞”。
关注【AdaCpp】公众号,我们将持续分享 GESP 和 CSP-J/S 竞赛的硬核干货与提分秘籍。
点击下方菜单栏,立即免费体验 AI 驱动的 C++ 在线编程平台,开启你的信奥夺牌之路!