唐巧的博客

GESP 大题核心考点

字数统计: 1.9k阅读时长: 8 min
2025/06/06

GESP 1 级

1 级主要考查分支和循环结构,所以大题的解法一般都是一个 for 循环,然后循环里面用 if 之类的条件判断做一些事情,最后再输出结果。其代码框架为:

1
2
3
// 循环结构, 例如 for ...
// 判断条件
// 输出结果

拿 GESP202309 一级题目:小明的幸运数 来说,其核心代码是:

1
2
3
4
5
6
7
8
9
10
// 循环
for (int i = l; i <= r; ++i) {
// 判断条件
if (isLucky(i)) {
// 累加
ans += i;
}
}
// 输出结果
cout << ans << endl;

另外一个例子,GESP202503 一级题目:四舍五入,核心代码:

1
2
3
4
5
6
7
8
9
10
11
// 循环
for (int i = 1; i <= n; ++i) {
cin >> a;
b = a%10;
a = a/10;
// 判断条件
if (b <= 4) a = a*10;
else a = a*10 + 10;
// 输出结果
cout << a << endl;
}

GESP 2 级

考点一:双重循环

GESP 2 级相对 1 级,对循环结构的考查进行了加强,一般需要用双层嵌套的循环才能完成大题。有一类双层嵌套循环需要特别关注,就是模拟输出类,这一类题过去考过多次,包括:

等差矩阵为例,其关键代码为嵌套的 for 循环,参考如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/**
* Author: Tang Qiao
*/
#include <bits/stdc++.h>
using namespace std;

int n, m;
int tu[55][55];
int main() {
cin >> n >> m;
// 嵌套的 for 循环
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
cout << i*j << " ";
}
cout << endl;
}
return 0;
}

如果学生还是不熟悉,可以考虑如下更多的练习:

  • 模仿 小杨的 X 字矩阵,输出 “又” 字,倒 “N” 字,“工” 字矩阵,“口”字矩阵
  • 模仿 画三角形,输出 左对齐、右对齐的正三角形,倒三角形
  • 模仿 等差矩阵,输出求和的矩阵,输出只有偶数的等差矩阵(奇数位填 *

考点二:常用函数

2 级还会考一些我们经常会实现的函数。包括:

求素质函数

参考题目:GESP202306 找素数

1
2
3
4
5
6
7
8
bool isPrime(int a) {
for (int i = 2; i*i <=a; i++) {
if (a%i == 0) {
return false;
}
}
return true;
}

求闰年函数

参考题目:GESP202503 时间跨越

关键代码:

1
2
3
4

bool isLeapYear(int year) {
return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0);
}

把一个数的每一位数字拆分的写法

参考题目:GESP202406 计数

关键代码:

1
2
3
4
5
6
7
8
int count(int a, int k) {
int ret = 0;
while (a) {
if (a%10 == k) ret++;
a/=10;
}
return ret;
}

练习题目:GESP202409 数位之和

GESP 3 级

考点一:字符串操作

3 级对字符串的操作要求非常高,需要考生灵活掌握字符串的变换、拼接、求子串、判断回文等操作。

求子串可以用 string 类的 substr(int pos, int len) 函数。需要注意该函数的两个参数分别是起始下标和长度。

其中,判断回文的写法如下:

1
2
3
4
5
6
7
8
9
bool isReverse(string &s) {
int len = s.length();
for (int i = 0; i < len/2; ++i) {
if (s[i] != s[len-i-1]) {
return false;
}
}
return true;
}

以真题 GESP202409 回文拼接 为例,考生需要对字符串进行切分,然后分别判断是否是回文串。

参考代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
/**
* Author: Tang Qiao
*/
#include <bits/stdc++.h>
using namespace std;

int n;
string s;

bool isReverse(string &s) {
int len = s.length();
for (int i = 0; i < len/2; ++i) {
if (s[i] != s[len-i-1]) {
return false;
}
}
return true;
}

int main() {
ios::sync_with_stdio(false);
cin >> n;
while (n--) {
cin >> s;
bool ans = false;
if (s.length() >= 4) {
for (int i = 2; i < s.length() - 1; i++) {
string s1 = s.substr(0, i);
string s2 = s.substr(i);
if (isReverse(s1) && isReverse(s2)) {
ans = true;
break;
}
}
}
if (ans) cout << "Yes" << endl;
else cout << "No" << endl;
}
return 0;
}

该考点的相关真题:

其中 GESP202309 进制判断 看起来是考进制的规则,实际上也是考字符串的查找。参考代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
/**
* Author: Tang Qiao
*/
#include <bits/stdc++.h>
using namespace std;

int isRange(string s, string range) {
for (int i = 0; i < s.length(); ++i) {
char ch = s[i];
int j = 0;
for (j=0; j<range.length(); ++j) {
if (ch == range[j]) {
break;
}
}
if (j == range.length()) return 0;
}
return 1;
}

int main() {
int n;
string s;
cin >> n;
while (n--) {
cin >> s;
cout << isRange(s, "01") << " "
<< isRange(s, "01234567") << " "
<< isRange(s, "0123456789") << " "
<< isRange(s, "0123456789ABCDEF") << endl;
}
return 0;
}

考点二:前缀和

前缀和的计算技巧是:用一个累加变量来不停地更新前 N 个数的和,这样我们只需要用 O(N)的时间复杂度,就可以把所有的前缀和求出来。

参考题目:GESP202409 平衡序列

此题解法是:暴力测试,先计算出总和 tot ,然后看前缀和的两倍有没有可能等于 tot。

参考代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
/**
* Author: Tang Qiao
*/
#include <bits/stdc++.h>
using namespace std;

int t, n, v[10010], tot;
int main() {
ios::sync_with_stdio(false);
cin >> t;
while (t--) {
cin >> n;
tot = 0;
for (int i = 0; i < n; ++i) {
cin >> v[i];
tot += v[i];
}
int cnt = 0;
bool ans = false;
for (int i = 0; i < n && cnt*2<tot; ++i) {
cnt += v[i];
if (cnt*2 == tot) {
ans = true;
}
}
if (ans) cout << "Yes" << endl;
else cout << "No" << endl;
}
return 0;
}

考点三:位运算

考生需要熟悉二进制,以及数的位运算操作。

典型考题为:GESP202503 2025

此题的思路如下:因为 x 最大是 2025,而如果 y 需要影响 x 的运算,只能与 x 的 bit 位是 1 的位进行操作。所以 y 如果存在,则必定小于 2048。因为 2048 的二进制 1 的 bit 位已经超过 2025 的最高位了。所以直接枚举 1~2048 之间的答案即可。

参考代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <bits/stdc++.h>
using namespace std;

int ans = -1;
int x;
int main() {
cin >> x;
for (int i = 1; i < 2048; ++i) {
if ((x & i) + (x | i) == 2025) {
ans = i;
break;
}
}
cout << ans << endl;
return 0;
}

GESP 4 级

考点比较散,以下是历次考题的考点。

  • GESP-202306 幸运数:模拟
  • GESP-202309 进制转换:进制转换
  • GESP-202309 变长编码:位操作
  • GESP-202312 小杨的字典:字符串操作
  • GESP-202312 田忌赛马:排序,模拟
  • GESP-202403 相似字符串:字符串操作
  • GESP-202403 做题:贪心
  • GESP-202406 黑白方块:枚举
  • GESP-202406 宝箱:枚举,二分
  • GESP-202409 黑白方块:枚举
  • GESP-202409 区间排序:排序
  • GESP-202412 Recamán:枚举
  • GESP-202412 字符排序:排序
  • GESP-202503 荒地开垦:枚举
  • GESP-202503 二阶矩阵:枚举

其中,比较常考的考点:

  • 枚举:考了 6 次。
  • 排序:考了 3 次。
  • 字符串操作:考了 2 次。

GESP 5 级

待补充

GESP 6 级

最近公共祖先

动态规划

包括 01 背包和完全背包:

基础动态规划:

记忆化搜索:

其它

树状数组:

暴力枚举:

模拟+高精度:

CATALOG
  1. 1. GESP 1 级
  2. 2. GESP 2 级
    1. 2.1. 考点一:双重循环
    2. 2.2. 考点二:常用函数
      1. 2.2.1. 求素质函数
      2. 2.2.2. 求闰年函数
      3. 2.2.3. 把一个数的每一位数字拆分的写法
  3. 3. GESP 3 级
    1. 3.1. 考点一:字符串操作
    2. 3.2. 考点二:前缀和
    3. 3.3. 考点三:位运算
  4. 4. GESP 4 级
  5. 5. GESP 5 级
  6. 6. GESP 6 级
    1. 6.1. 最近公共祖先
    2. 6.2. 动态规划
    3. 6.3. 其它