GESP C++ 三级真题详细分析讲解

四季读书网 3 0
GESP C++ 三级真题详细分析讲解

GESP C++ 三级真题详细分析讲解

GESP C++ 三级整体属于 “从循环基础过渡到数组 / 字符串 / 位运算” 的阶段。它不再只考简单循环和枚举,而是开始要求选手能够使用 一维数组、字符串、简单位运算 来解决问题。

按照 GESP 三级的知识范围,真题核心基本集中在三大类:

  1. 1. 简单字符串
  2. 2. 简单位运算
  3. 3. 一维数组枚举

注意:GESP 三级一般 不应涉及递归、动态规划、二分、图论、GCD、质因数分解、复杂排序 等内容。


一、GESP C++ 三级知识点定位

三级核心能力

模块
主要内容
典型考法
字符串
string
、字符数组、字符遍历、字符统计
判断回文、统计字符、大小写转换、简单加密
一维数组
数组存储、遍历、标记、计数
找最大最小、统计出现次数、去重、查找
位运算
&
|^<<>>
判断奇偶、统计二进制 1 的个数、异或性质

二、三级真题整体特点

1. 题目难度特点

GESP C++ 三级题目通常有以下特点:

  • • 代码量一般在 20 到 60 行
  • • 很少需要复杂算法设计
  • • 更重视:
    • ◦ 基本语法熟练度
    • ◦ 循环边界
    • ◦ 数组下标
    • ◦ 字符处理
    • ◦ 位运算理解
  • • 题目通常可以用 模拟 + 枚举 + 基础数据结构 完成

2. 常见失分点

失分点
说明
数组下标越界
a[0]
 和 a[1] 起始混乱
字符和数字混淆
'0'
 与 0 不同
字符串长度处理错误
s.size()
 返回的是长度,最后一个下标是 s.size()-1
大小写转换不熟
'A'
 到 'Z''a' 到 'z' 的 ASCII 差值为 32
位运算优先级错误
x & 1 == 1
 应写成 (x & 1) == 1
没有初始化数组
计数数组必须初始化为 0

三、模块一:字符串真题分析

1. 常考题型一:字符统计

题型描述

给定一个字符串,统计其中某类字符的数量,例如:

  • • 小写字母数量
  • • 大写字母数量
  • • 数字字符数量
  • • 某个指定字符出现次数

核心知识

string s;cin >> s;for (int i = 0; i < s.size(); i++) {if (s[i] >= 'a' && s[i] <= 'z') {// 小写字母    }}

典型思路

遍历字符串中的每个字符,根据 ASCII 范围判断类型。

示例讲解

假设题目要求统计字符串中数字字符的数量。

#include<bits/stdc++.h>usingnamespace std;intmain(){    string s;    cin >> s;int cnt = 0;for (int i = 0; i < s.size(); i++) {if (s[i] >= '0' && s[i] <= '9') {            cnt++;        }    }    cout << cnt << endl;return0;}

易错点

if (s[i] >= 0 && s[i] <= 9)

这是错误的。因为 s[i] 是字符,数字字符应该写成:

'0' 到 '9'

而不是整数 0 到 9


2. 常考题型二:大小写转换

题型描述

给定一个字符串,将其中的大写字母变成小写,或者小写字母变成大写。

核心知识

ASCII 中:

'a' - 'A' == 32

所以:

大写转小写:ch = ch + 32;小写转大写:ch = ch - 32;

也可以使用函数:

tolower(ch)toupper(ch)

但考试中建议理解 ASCII 原理。

示例代码

#include<bits/stdc++.h>usingnamespace std;intmain(){    string s;    cin >> s;for (int i = 0; i < s.size(); i++) {if (s[i] >= 'A' && s[i] <= 'Z') {            s[i] = s[i] + 32;        }    }    cout << s << endl;return0;}

易错点

只转换了字母,没有判断是否是大写:

s[i] = s[i] + 32;

这样会把数字、符号也改掉,导致错误。


3. 常考题型三:回文字符串判断

题型描述

判断一个字符串正着读和反着读是否相同。

例如:

aba 是回文abba 是回文abc 不是回文

核心思路

用两个指针:

  • • l 从左往右
  • • r 从右往左

不断比较:

s[l] == s[r]

示例代码

#include<bits/stdc++.h>usingnamespace std;intmain(){    string s;    cin >> s;bool ok = true;int l = 0, r = s.size() - 1;while (l < r) {if (s[l] != s[r]) {            ok = false;break;        }        l++;        r--;    }if (ok) cout << "Yes" << endl;else cout << "No" << endl;return0;}

易错点

字符串最后一个字符下标不是 s.size(),而是:

s.size() - 1

4. 常考题型四:简单加密 / 解密

题型描述

给定一个字符串,将每个字符按一定规则移动。

例如:

a -> bb -> cz -> a

这是最基础的凯撒加密。

示例代码

#include<bits/stdc++.h>usingnamespace std;intmain(){    string s;    cin >> s;for (int i = 0; i < s.size(); i++) {if (s[i] >= 'a' && s[i] <= 'z') {if (s[i] == 'z') s[i] = 'a';else s[i]++;        }    }    cout << s << endl;return0;}

进阶写法

s[i] = (s[i] - 'a' + 1) % 26 + 'a';

但三级阶段如果刚接触,推荐先用分支写清楚。


四、模块二:一维数组真题分析

1. 常考题型一:数组求最大值 / 最小值

题型描述

输入 n 个整数,求最大值、最小值或它们的位置。

示例代码

#include<bits/stdc++.h>usingnamespace std;intmain(){int n;    cin >> n;int a[105];for (int i = 1; i <= n; i++) {        cin >> a[i];    }int mx = a[1];for (int i = 2; i <= n; i++) {if (a[i] > mx) {            mx = a[i];        }    }    cout << mx << endl;return0;}

易错点

如果数组从 1 开始存:

for (int i = 1; i <= n; i++)

如果数组从 0 开始存:

for (int i = 0; i < n; i++)

两种都可以,但不能混用。


2. 常考题型二:计数数组 / 桶思想

题型描述

统计每个数字出现了多少次。

例如输入:

51 2 2 3 1

输出每个数字的出现次数。

核心思想

如果数字范围较小,比如 0 ~ 100,可以开数组:

int cnt[101] = {};

然后:

cnt[x]++;

示例代码

#include<bits/stdc++.h>usingnamespace std;intmain(){int n;    cin >> n;int cnt[101] = {};for (int i = 1; i <= n; i++) {int x;        cin >> x;        cnt[x]++;    }for (int i = 0; i <= 100; i++) {if (cnt[i] > 0) {            cout << i << " " << cnt[i] << endl;        }    }return0;}

易错点

数组大小要能覆盖数据范围。

如果 x 可能到 1000,就不能只开:

int cnt[101];

3. 常考题型三:数组查找

题型描述

输入一个数组,再输入一个目标数 x,判断它是否出现过。

示例代码

#include<bits/stdc++.h>usingnamespace std;intmain(){int n, x;    cin >> n;int a[105];for (int i = 1; i <= n; i++) {        cin >> a[i];    }    cin >> x;bool found = false;for (int i = 1; i <= n; i++) {if (a[i] == x) {            found = true;break;        }    }if (found) cout << "Yes" << endl;else cout << "No" << endl;return0;}

考查重点

  • • 数组输入
  • • 数组遍历
  • • bool 变量
  • • 找到后及时 break

4. 常考题型四:数组去重

题型描述

输入若干整数,输出不同数字的个数。

如果数字范围小,可以用计数数组。

示例代码

#include<bits/stdc++.h>usingnamespace std;intmain(){int n;    cin >> n;int cnt[1001] = {};int ans = 0;for (int i = 1; i <= n; i++) {int x;        cin >> x;if (cnt[x] == 0) {            ans++;        }        cnt[x]++;    }    cout << ans << endl;return0;}

易错点

不要每次都 ans++,只有第一次出现时才加。


五、模块三:位运算真题分析

位运算是 GESP 三级比较有区分度的内容,很多同学第一次接触会觉得抽象。

1. 位运算基础表

运算符
名称
含义
&
按位与
两位都是 1,结果才是 1
|
按位或
有一个是 1,结果就是 1
^
按位异或
两位不同结果为 1,相同为 0
<<
左移
相当于乘以 2
>>
右移
相当于除以 2 取整

2. 常考题型一:判断奇偶

原理

一个整数的二进制最低位:

  • • 是 1,说明它是奇数
  • • 是 0,说明它是偶数

所以:

if (x & 1)

可以判断 x 是否为奇数。

示例代码

#include<bits/stdc++.h>usingnamespace std;intmain(){int x;    cin >> x;if (x & 1) cout << "odd" << endl;else cout << "even" << endl;return0;}

易错点

建议写成:

if ((x & 1) == 1)

这样更清楚。


3. 常考题型二:统计二进制中 1 的个数

题型描述

输入一个整数,统计它的二进制表示中有多少个 1

例如:

13 的二进制是 1101,有 3 个 1

基础做法

不断判断最低位,然后右移。

#include<bits/stdc++.h>usingnamespace std;intmain(){int x;    cin >> x;int cnt = 0;while (x > 0) {if (x & 1) cnt++;        x >>= 1;    }    cout << cnt << endl;return0;}

过程示例

以 x = 13 为例:

13 = 1101,最低位是 1,cnt = 1右移后 6 = 110,最低位是 0右移后 3 = 11,最低位是 1,cnt = 2右移后 1 = 1,最低位是 1,cnt = 3

4. 常考题型三:异或性质

异或的重要性质

a ^ a = 0a ^ 0 = a

所以,如果一组数中只有一个数出现一次,其他数都出现两次,可以用异或找到那个数。

示例

输入:

51 2 3 2 1

结果是:

3

代码

#include<bits/stdc++.h>usingnamespace std;intmain(){int n;    cin >> n;int ans = 0;for (int i = 1; i <= n; i++) {int x;        cin >> x;        ans ^= x;    }    cout << ans << endl;return0;}

原理

1 ^ 2 ^ 3 ^ 2 ^ 1= 1 ^ 1 ^ 2 ^ 2 ^ 3= 0 ^ 0 ^ 3= 3

六、三级真题常见题型总结

1. 字符串类题目

题型
核心方法
字符统计
遍历字符串,用 if 判断字符范围
大小写转换
ASCII 差值或 tolower / toupper
回文判断
双指针从两端向中间比较
简单加密
字符移动,注意循环回到开头
字符串比较
使用 == 或逐字符比较

2. 数组类题目

题型
核心方法
求最大最小值
遍历更新答案
查找元素
遍历判断是否存在
统计次数
计数数组
去重
第一次出现时计数
标记出现情况
bool vis[]
 或 int cnt[]

3. 位运算类题目

题型
核心方法
判断奇偶
x & 1
统计二进制 1 的个数
右移 + 判断最低位
求第 k 位
(x >> k) & 1
异或消除
a ^ a = 0
乘除 2
x << 1
x >> 1

七、三级考试解题流程建议

遇到 GESP 三级题目,可以按下面顺序分析:

第一步:判断题型

先问自己:

  1. 1. 题目是否处理一串字符?是 → 可能是字符串题。
  2. 2. 题目是否输入很多数,需要存起来?是 → 可能是数组题。
  3. 3. 题目是否提到二进制、异或、按位操作?是 → 可能是位运算题。

第二步:确定数据结构

情况
建议使用
处理一个单词或一行文本
string
存储多个整数
int a[]
统计数字出现次数
int cnt[]
标记是否出现过
bool vis[]
处理二进制位
位运算

第三步:写循环

三级题大多数本质上是:

for 或 while 遍历全部数据

所以要特别注意循环范围:

for (int i = 0; i < s.size(); i++)

或者:

for (int i = 1; i <= n; i++)

第四步:检查边界

常见边界包括:

  • • 字符串长度为 1
  • • 数组只有 1 个元素
  • • 数字为 0
  • • 全部字符相同
  • • 全部数字相同
  • • 最大值或最小值出现在第一个位置

八、三级备考重点

1. 必须熟练掌握的代码模板

字符串遍历

for (int i = 0; i < s.size(); i++) {// 处理 s[i]}

数组输入

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

计数数组

int cnt[1005] = {};cnt[x]++;

判断奇偶

if (x & 1) {// 奇数}

统计二进制 1

int cnt = 0;while (x > 0) {    cnt += x & 1;    x >>= 1;}

九、三级真题难度分布

通常一套 GESP C++ 三级卷子的难度分布类似:

题目位置
难度
常见内容
第 1 题
较简单
字符串统计 / 数组基础
第 2 题
中等
数组枚举 / 计数
第 3 题
中等偏上
字符串综合 / 位运算
第 4 题
较难
数组 + 枚举 / 位运算综合

十、三级学习建议

如果你要备考 GESP C++ 三级,建议按这个顺序复习:

第一阶段:补基础

重点练:

  • • string 输入输出
  • • 字符串遍历
  • • 数组输入输出
  • • 数组最大最小值
  • • 计数数组

第二阶段:专项突破

重点练:

  • • 回文判断
  • • 字符统计
  • • 数组去重
  • • 桶计数
  • • 异或运算
  • • 二进制 1 的个数

第三阶段:真题训练

做真题时建议:

  1. 1. 先独立完成,不看题解
  2. 2. 卡住 20 分钟后再看提示
  3. 3. 做完后总结:
    • ◦ 是字符串题?
    • ◦ 是数组题?
    • ◦ 是位运算题?
    • ◦ 错在思路还是代码细节?

十一、三级到四级的衔接

GESP 三级通过后,四级主要会进入:

  1. 1. 二维数组
  2. 2. 多关键字排序

所以三级阶段结束前,至少要保证:

  • • 一维数组非常熟练
  • • 字符串遍历没有问题
  • • 能自己写简单比较逻辑
  • • 理解数组下标和循环边界

如果三级能稳定达到 90 分以上,就可以开始准备四级。

如果三级在 60~80 分,建议先不要急着冲四级,应重点补:

  • • 数组统计
  • • 字符串处理
  • • 位运算基础

十二、总结

GESP C++ 三级的核心不是复杂算法,而是:

"

会用字符串处理文本,会用一维数组存储和统计数据,会用简单位运算解决二进制问题。

重点掌握三句话:

  1. 1. 字符串题:遍历每个字符,按规则判断。
  2. 2. 数组题:存储数据后遍历、统计、查找。
  3. 3. 位运算题:理解最低位、右移、异或消除。

如果你能熟练完成这些类型,GESP C++ 三级基本可以稳定通过,甚至冲击 90 分以上。

重要事情说三遍:
点击查看原文可以刷GESP历年真题!
点击查看原文可以刷GESP历年真题!
点击查看原文可以刷GESP历年真题!

抱歉,评论功能暂时关闭!