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

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

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

GESP C++ 四级是从“基础语法 + 一维数组”过渡到“二维数组 + 排序应用”的阶段。

和三级相比,四级最明显的变化是:

  1. 1. 数据从一维变成二维
  2. 2. 排序从简单排序变成多关键字排序
  3. 3. 题目更强调下标、坐标、比较规则和模拟过程

按照 GESP 四级的知识范围,核心内容主要有两大类:

  • • 简单二维数组
  • • 多关键字排序

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


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

1. 四级核心知识点

模块
核心内容
常见考法
二维数组
矩阵输入输出、行列遍历、行列统计、对角线处理
矩阵求和、转置、最大值位置、简单网格模拟
多关键字排序
sort
 + 结构体 + 自定义比较函数
成绩排序、排名排序、按多个条件排序

2. 四级与三级的区别

级别
核心内容
特点
三级
字符串、一维数组、简单位运算
数据通常是一串字符或一列数
四级
二维数组、多关键字排序
数据变成表格、矩阵、多个属性对象

举例来说:

三级常见题:

输入 n 个数,统计某个数出现几次。

四级常见题:

输入 n 行 m 列的矩阵,统计每一行、每一列的和。

三级排序可能只是:

把一组数从小到大排序。

四级排序可能变成:

学生按总分从高到低排序,总分相同按语文分从高到低,仍相同按编号从小到大。

二、四级真题整体特点

1. 题目难度特点

GESP C++ 四级题目一般有以下特点:

  • • 代码量通常在 30 到 80 行
  • • 题目不会太复杂,但细节较多
  • • 常见输入规模不大,暴力遍历通常可以通过
  • • 重点考查:
    • ◦ 二维数组下标
    • ◦ 行列循环顺序
    • ◦ 坐标转换
    • ◦ 排序比较函数
    • ◦ 结构体数组使用

2. 常见失分点

失分点
说明
行列下标写反
a[i][j]
 中 i 是行,j 是列
循环边界错误
i <= n
 和 i < n 混用
二维数组开小
a[105][105]
 要覆盖最大数据范围
转置时行列输出错误
原来是 n × m,转置后是 m × n
排序比较函数写反
降序应写 >,升序应写 <
多关键字排序漏条件
第一关键字相同后必须比较第二关键字
没有处理完全相同情况
最后通常要用编号保证顺序稳定
结构体字段混乱
score
idsum 等变量含义要清楚

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

二维数组是 GESP 四级最重要的内容之一。它的本质是“表格”。

例如:

3 行 4 列矩阵:1 2 3 45 6 7 89 1 2 3

可以用:

int a[105][105];

来存储。


1. 常考题型一:矩阵输入与输出

题型描述

输入一个 n 行 m 列的矩阵,按照要求输出。

核心代码

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

输出:

for (int i = 1; i <= n; i++) {for (int j = 1; j <= m; j++) {        cout << a[i][j] << " ";    }    cout << endl;}

考查重点

  • • 双重循环
  • • 行列顺序
  • • 二维数组下标

易错点

很多同学会把行列写反:

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

如果题目说的是 n 行 m 列,一般应写:

i = 1 到 nj = 1 到 m

2. 常考题型二:矩阵总和、行和、列和

题型描述

给定一个矩阵,求:

  • • 所有元素之和
  • • 每一行的和
  • • 每一列的和
  • • 最大行和 / 最大列和

2.1 求矩阵总和

示例代码

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

思路

读入时直接累加即可,不一定非要读完后再算。


2.2 求每一行的和

for (int i = 1; i <= n; i++) {int rowSum = 0;for (int j = 1; j <= m; j++) {        rowSum += a[i][j];    }    cout << rowSum << endl;}

这里固定的是行 i,变化的是列 j


2.3 求每一列的和

for (int j = 1; j <= m; j++) {int colSum = 0;for (int i = 1; i <= n; i++) {        colSum += a[i][j];    }    cout << colSum << endl;}

这里固定的是列 j,变化的是行 i


2.4 行和与列和的区别

要求
外层循环
内层循环
求每一行的和
行 i
列 j
求每一列的和
列 j
行 i

很多四级同学在这里容易混。


3. 常考题型三:矩阵最大值及其位置

题型描述

输入一个矩阵,找到最大值以及它所在的位置。

示例代码

#include<bits/stdc++.h>usingnamespace std;intmain(){int n, m;    cin >> n >> m;int a[105][105];for (int i = 1; i <= n; i++) {for (int j = 1; j <= m; j++) {            cin >> a[i][j];        }    }int maxValue = a[1][1];int maxRow = 1, maxCol = 1;for (int i = 1; i <= n; i++) {for (int j = 1; j <= m; j++) {if (a[i][j] > maxValue) {                maxValue = a[i][j];                maxRow = i;                maxCol = j;            }        }    }    cout << maxValue << " " << maxRow << " " << maxCol << endl;return0;}

易错点

不要把最大值初始成 0

如果矩阵中可能有负数:

int maxValue = 0;

可能会出错。

更稳妥写法是:

int maxValue = a[1][1];

4. 常考题型四:矩阵转置

题型描述

给定一个 n × m 的矩阵,输出它的转置矩阵。

原矩阵:

1 2 34 5 6

是 2 × 3

转置后:

1 42 53 6

是 3 × 2

核心规律

原来的:

a[i][j]

转置后变成:

a[j][i]

示例代码

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

重点理解

输出时:

  • • 原来的列 j 变成新的行
  • • 原来的行 i 变成新的列

所以外层循环是:

j = 1 到 m

内层循环是:

i = 1 到 n

5. 常考题型五:主对角线与副对角线

这类题通常出现在方阵中,也就是 n × n 的矩阵。


5.1 主对角线

主对角线位置满足:

i == j

例如:

a[1][1]a[2][2]a[3][3]

代码:

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

5.2 副对角线

副对角线位置满足:

i + j == n + 1

也就是:

j = n - i + 1

代码:

int sum = 0;for (int i = 1; i <= n; i++) {    sum += a[i][n - i + 1];}

5.3 两条对角线之和

int sum = 0;for (int i = 1; i <= n; i++) {    sum += a[i][i];    sum += a[i][n - i + 1];}if (n % 2 == 1) {    sum -= a[n / 2 + 1][n / 2 + 1];}

为什么要减一次?

当 n 是奇数时,中心点同时属于主对角线和副对角线。

例如 3 × 3

1 2 34 5 67 8 9

中心 5 被加了两次,所以要减一次。


6. 常考题型六:简单网格模拟

题型描述

给定一个二维网格,根据规则修改某些格子或统计某些格子。

常见形式:

  • • 标记某一行、某一列
  • • 判断某个格子的上下左右
  • • 统计周围满足条件的格子数量
  • • 简单地图移动

6.1 四方向相邻格子

对于格子 (x, y),上下左右分别是:

方向
新坐标
(x - 1, y)
(x + 1, y)
(x, y - 1)
(x, y + 1)

可以写成方向数组:

int dx[4] = {-1100};int dy[4] = {00-11};

使用:

for (int k = 0; k < 4; k++) {int nx = x + dx[k];int ny = y + dy[k];if (nx >= 1 && nx <= n && ny >= 1 && ny <= m) {// 合法格子    }}

注意

这里的方向数组只是普通数组和循环,不是图论搜索。GESP 四级可以出现简单的相邻格子判断,但不应出现 BFS、DFS 这类图论算法。


6.2 统计周围格子

例如统计每个格子上下左右有多少个 1

int cnt = 0;for (int k = 0; k < 4; k++) {int nx = i + dx[k];int ny = j + dy[k];if (nx >= 1 && nx <= n && ny >= 1 && ny <= m) {if (a[nx][ny] == 1) {            cnt++;        }    }}

易错点

一定要先判断坐标是否合法,再访问数组:

错误写法:

if (a[nx][ny] == 1 && nx >= 1 && nx <= n)

这样可能在 nx 越界时已经访问了数组,导致错误。

正确写法:

if (nx >= 1 && nx <= n && ny >= 1 && ny <= m) {if (a[nx][ny] == 1) {        cnt++;    }}

四、模块二:多关键字排序真题分析

多关键字排序是 GESP 四级的另一个核心。

所谓“多关键字排序”,就是排序时不只看一个条件,而是按多个条件依次比较。


1. 什么是多关键字排序?

例如学生成绩排序:

规则如下:

  1. 1. 总分高的排前面
  2. 2. 总分相同,语文分高的排前面
  3. 3. 总分和语文都相同,编号小的排前面

这就叫多关键字排序。


2. 结构体基础

如果每个学生有多个属性,用结构体存储最方便:

structStudent {int id;int chinese;int math;int english;int total;};

定义数组:

Student a[105];

读入:

for (int i = 1; i <= n; i++) {    a[i].id = i;    cin >> a[i].chinese >> a[i].math >> a[i].english;    a[i].total = a[i].chinese + a[i].math + a[i].english;}

3. sort 自定义比较函数

基本格式

boolcmp(Student x, Student y){return x.total > y.total;}

使用:

sort(a + 1, a + n + 1, cmp);

如果数组从 0 开始:

sort(a, a + n, cmp);

4. 常考题型一:成绩排序

题型描述

输入若干学生的成绩,按照总分从高到低排序,如果总分相同,再按某一科成绩排序,最后按编号排序。

示例代码

#include<bits/stdc++.h>usingnamespace std;structStudent {int id;int chinese;int math;int english;int total;};boolcmp(Student a, Student b){if (a.total != b.total) {return a.total > b.total;       // 总分高的在前    }if (a.chinese != b.chinese) {return a.chinese > b.chinese;   // 语文高的在前    }return a.id < b.id;                 // 编号小的在前}intmain(){int n;    cin >> n;    Student stu[305];for (int i = 1; i <= n; i++) {        stu[i].id = i;        cin >> stu[i].chinese >> stu[i].math >> stu[i].english;        stu[i].total = stu[i].chinese + stu[i].math + stu[i].english;    }sort(stu + 1, stu + n + 1, cmp);for (int i = 1; i <= n; i++) {        cout << stu[i].id << " " << stu[i].total << endl;    }return0;}

5. 比较函数怎么写?

比较函数的核心问题是:

"

如果 a 应该排在 b 前面,就返回 true。

例如:

return a.total > b.total;

表示总分大的排前面。

return a.id < b.id;

表示编号小的排前面。


6. 多关键字排序模板

推荐背熟这个模板:

boolcmp(Node a, Node b){if (a.x != b.x) return a.x > b.x;if (a.y != b.y) return a.y < b.y;return a.id < b.id;}

含义:

  1. 1. 先按 x 从大到小
  2. 2. x 相同按 y 从小到大
  3. 3. 还相同按 id 从小到大

7. 常考题型二:排名问题

题型描述

按照分数排序后,输出前若干名,或者输出每个人的排名。

四级阶段常见的是简单排序后输出,不会涉及复杂的数据结构。

示例:输出前 5 名

sort(a + 1, a + n + 1, cmp);for (int i = 1; i <= 5 && i <= n; i++) {    cout << a[i].id << " " << a[i].score << endl;}

注意

如果题目要求“同分同名次”,需要额外处理。但四级常见题一般只是排序后按顺序输出。


8. 常考题型三:按字典序或字符串排序

有时排序对象中包含字符串,例如姓名。

structPerson {    string name;int score;};

比较函数:

boolcmp(Person a, Person b){if (a.score != b.score) return a.score > b.score;return a.name < b.name;}

string 可以直接比较:

"a" < "b""abc" < "abd"

这是按照字典序比较。


五、四级真题常见综合题型

GESP 四级有时会把二维数组和排序结合起来,但仍然不会太复杂。


1. 题型一:统计每一行成绩并排序

题型描述

有 n 个学生,每个学生有 m 门成绩,求每个人总分,并按总分排序。

分析

输入可以看作二维表:

学生1:成绩1 成绩2 成绩3学生2:成绩1 成绩2 成绩3...

可以不用真正存整个二维数组,只需要读入时累加总分。

示例代码

#include<bits/stdc++.h>usingnamespace std;structStudent {int id;int sum;};boolcmp(Student a, Student b){if (a.sum != b.sum) return a.sum > b.sum;return a.id < b.id;}intmain(){int n, m;    cin >> n >> m;    Student a[105];for (int i = 1; i <= n; i++) {        a[i].id = i;        a[i].sum = 0;for (int j = 1; j <= m; j++) {int x;            cin >> x;            a[i].sum += x;        }    }sort(a + 1, a + n + 1, cmp);for (int i = 1; i <= n; i++) {        cout << a[i].id << " " << a[i].sum << endl;    }return0;}

2. 题型二:矩阵中找特殊位置

题型描述

给定一个矩阵,找满足某种条件的位置,例如:

  • • 是所在行最大值
  • • 是所在列最小值
  • • 周围格子满足某种条件
  • • 某一行或某一列的和最大

分析方法

这类题关键是拆成两步:

  1. 1. 枚举每一个位置
  2. 2. 判断这个位置是否满足条件

示例:判断某个元素是否是所在行最大值

bool ok = true;for (int j = 1; j <= m; j++) {if (a[i][j] > a[i][pos]) {        ok = false;    }}

如果还要判断它是否是所在列最小值:

for (int k = 1; k <= n; k++) {if (a[k][pos] < a[i][pos]) {        ok = false;    }}

六、四级真题解题流程

遇到 GESP 四级题,可以按下面步骤分析。


第一步:判断题型

先看题目数据形式:

如果是表格 / 矩阵 / 棋盘

基本属于二维数组题。

常见关键词:

n 行 m 列矩阵方阵棋盘地图表格对角线上下左右

如果是学生 / 选手 / 商品 / 多个属性

基本属于结构体排序题。

常见关键词:

成绩排名编号姓名总分按……排序若相同则……优先级

第二步:确定存储方式

题目类型
推荐存储
矩阵、棋盘
int a[105][105]
 或 char mp[105][105]
学生、选手
struct Student
每行有多个属性
结构体数组
只需要行和 / 总分
可以边读边累加,不一定存整个矩阵

第三步:写清楚循环范围

二维数组最重要的是循环边界:

for (int i = 1; i <= n; i++) {for (int j = 1; j <= m; j++) {// a[i][j]    }}

其中:

  • • i 表示第几行
  • • j 表示第几列

第四步:排序题先写比较规则

排序题不要急着写代码,先把规则翻译成比较函数。

例如题目说:

总分高的在前;总分相同,编号小的在前。

就写:

boolcmp(Node a, Node b){if (a.sum != b.sum) return a.sum > b.sum;return a.id < b.id;}

七、四级常见代码模板

模板一:二维数组输入

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

模板二:矩阵遍历

for (int i = 1; i <= n; i++) {for (int j = 1; j <= m; j++) {// 处理 a[i][j]    }}

模板三:行和

for (int i = 1; i <= n; i++) {int sum = 0;for (int j = 1; j <= m; j++) {        sum += a[i][j];    }    cout << sum << endl;}

模板四:列和

for (int j = 1; j <= m; j++) {int sum = 0;for (int i = 1; i <= n; i++) {        sum += a[i][j];    }    cout << sum << endl;}

模板五:转置输出

for (int j = 1; j <= m; j++) {for (int i = 1; i <= n; i++) {        cout << a[i][j] << " ";    }    cout << endl;}

模板六:结构体排序

structNode {int id;int x;int y;};boolcmp(Node a, Node b){if (a.x != b.x) return a.x > b.x;if (a.y != b.y) return a.y < b.y;return a.id < b.id;}

模板七:排序调用

sort(a + 1, a + n + 1, cmp);

八、四级考试常见题型总结

1. 二维数组类

题型
核心做法
矩阵输入输出
双重循环
矩阵求和
遍历累加
行和 / 列和
固定一维,遍历另一维
最大值位置
遍历更新最大值和坐标
转置矩阵
输出 a[i][j] 时交换行列顺序
对角线
主对角线 i == j,副对角线 i + j == n + 1
简单网格统计
判断上下左右坐标是否合法

2. 多关键字排序类

题型
核心做法
成绩排序
结构体存编号和成绩
排名输出
排序后按顺序输出
多条件比较
if
 分层比较
字符串排序
string
 可直接比较
总分排序
读入时计算总分
编号兜底
最后用 id 保证顺序明确

九、四级真题中的重点难点

1. 二维数组难点:坐标意识

很多同学学二维数组时最大的问题不是不会写循环,而是没有坐标意识。

建议始终记住:

a[i][j]

表示:

第 i 行,第 j 列

不要把 i 和 j 的含义混掉。


2. 二维数组难点:边界判断

如果题目涉及上下左右,一定要判断:

nx >= 1 && nx <= n && ny >= 1 && ny <= m

否则可能越界。


3. 排序难点:比较函数返回值

比较函数不是判断谁“大”,而是判断:

"

第一个参数是否应该排在第二个参数前面。

例如:

boolcmp(Node a, Node b){return a.score > b.score;}

意思是:

如果 a 的分数比 b 高,那么 a 应该排在 b 前面。

4. 排序难点:多条件顺序

题目中条件的先后顺序非常重要。

例如:

先按总分从高到低;总分相同按语文从高到低;语文也相同按编号从小到大。

代码必须按这个顺序写:

if (a.total != b.total) return a.total > b.total;if (a.chinese != b.chinese) return a.chinese > b.chinese;return a.id < b.id;

不能把编号放到前面比较。


十、四级真题难度分布

一套 GESP C++ 四级题通常可以这样理解:

题目位置
常见难度
常见内容
第 1 题
较简单
二维数组基础遍历 / 行列统计
第 2 题
中等
矩阵处理 / 坐标判断
第 3 题
中等偏上
多关键字排序
第 4 题
较难
二维数组综合模拟 / 排序综合

当然具体年份会有变化,但整体不会脱离“二维数组 + 多关键字排序”的主线。


十一、四级备考重点

第一阶段:二维数组基础

必须熟练:

  • • 输入 n × m 矩阵
  • • 输出矩阵
  • • 求总和
  • • 求行和
  • • 求列和
  • • 找最大值和位置

目标是看到矩阵题能马上写出双重循环。


第二阶段:二维数组进阶

重点练:

  • • 矩阵转置
  • • 主对角线 / 副对角线
  • • 上下左右相邻格子
  • • 简单网格模拟
  • • 行列最大最小值

第三阶段:排序专项

重点练:

  • • 结构体定义
  • • sort 使用
  • • 自定义比较函数
  • • 多关键字排序
  • • 成绩排序
  • • 编号排序
  • • 字符串字典序排序

第四阶段:综合真题训练

做真题时建议:

  1. 1. 先独立思考题型
  2. 2. 判断是二维数组还是排序
  3. 3. 写出核心循环或比较函数
  4. 4. 再补完整代码
  5. 5. 做完后检查边界和排序规则

十二、从四级到五级的衔接

GESP 四级通过后,五级会进入明显更难的阶段,主要包括:

  • • GCD / LCM
  • • 质因数分解
  • • 筛法
  • • 快速幂
  • • 二分查找 / 二分答案
  • • 前缀和与差分
  • • 更复杂的贪心
  • • 哈希表应用

因此,四级和五级之间的跨度较大。

如果你四级能稳定达到 90 分以上,可以开始学习五级内容。

如果四级只有 60 到 80 分,建议先不要急着进入五级,应重点补:

  • • 二维数组行列遍历
  • • 矩阵转置
  • • 对角线处理
  • • 排序比较函数
  • • 结构体数组

十三、四级考前检查清单

考前可以问自己以下问题:

二维数组部分

  • • 我能不能独立写出 n × m 矩阵输入?
  • • 我是否清楚 a[i][j] 中 i 是行,j 是列?
  • • 我能不能求每一行的和?
  • • 我能不能求每一列的和?
  • • 我能不能输出转置矩阵?
  • • 我是否知道主对角线和副对角线的下标规律?
  • • 我能不能判断上下左右坐标是否合法?

排序部分

  • • 我会不会定义结构体?
  • • 我会不会写 sort(a + 1, a + n + 1, cmp)
  • • 我是否理解 cmp(a, b) 返回 true 的含义?
  • • 我能不能写出总分降序、编号升序?
  • • 我能不能处理三个以上关键字的排序?
  • • 我是否会用 string 进行字典序比较?

十四、总结

GESP C++ 四级的核心可以概括为两句话:

"

二维数组题,看清行列,用双重循环处理。排序题,看清优先级,用结构体和比较函数实现。

四级并不追求复杂算法,而是考查你是否能熟练处理“表格数据”和“多条件排序”。

最重要的两个能力是:

  1. 1. 二维数组坐标能力
    • ◦ 行、列、对角线、上下左右
  2. 2. 多关键字比较能力
    • ◦ 谁优先、升序还是降序、相同怎么办

如果这两部分都熟练,GESP C++ 四级基本可以稳定通过,并且能为五级的数论、二分、前缀和等内容打好基础。

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

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