外观
2024年12月 GESP C++ 四级真题解析
一、单选题(每题2分,共30分)
选择题答案
| 题号 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 答案 | A | B | B | B | D | D | D | D | A | C | B | B | A | C | A |
登录后查看内容
此内容需要登录后才能查看,请先登录您的账户。
1级权限
需要 1 级或以上权限1. 下面的语句中,()正确定义了一个计算浮点数 x 的平方 x² = x × x 的函数,并成功调用该函数。
A.
cpp
float square(float x){
return x * x;
}
float area = square(2);1
2
3
4
2
3
4
B.
cpp
square(float x){
return x * x;
}
float area = square(2);1
2
3
4
2
3
4
C.
cpp
void square(float x){
return x * x;
}
float area = square(2.0);1
2
3
4
2
3
4
D.
cpp
void square(float x){
x * x;
return;
}
float area = square(2);1
2
3
4
5
2
3
4
5
查看解析
答案:A
考纲知识点: 函数定义与调用
解析: A 选项函数返回类型、参数列表、调用方式均正确;B 缺少返回类型;C 用 void 却 return 值;D 无返回值且计算结果未保存。
登录后查看内容
此内容需要登录后才能查看,请先登录您的账户。
1级权限
需要 1 级或以上权限2. 下面代码的描述中,正确的是()。
cpp
void n_chars(char c, int n){
while (n-- > 0)
cout << c;
}
char my_char = 'w';
int times = 5;
n_chars(my_char, times);1
2
3
4
5
6
7
2
3
4
5
6
7
A. 代码执行结束后,times 的值为 0
B. n 是形参,times 是实参
C. n 是实参,times 是形参
D. 代码最后一行换成 n_chars(times, my_char); 也可以
查看解析
答案:B
考纲知识点: 形参与实参
解析: n 是函数定义时的形参,times 是调用时传入的实参;times 的值不会被函数修改(值传递)。
登录后查看内容
此内容需要登录后才能查看,请先登录您的账户。
1级权限
需要 1 级或以上权限3. 给定以下代码,执行后变量 a 的值为()。
cpp
void func(int& x){
x = x * 2;
}
int a = 5;
func(a);1
2
3
4
5
2
3
4
5
A. 5
B. 10
C. 15
D. 20
查看解析
答案:B
考纲知识点: 引用传递
解析: 引用参数 x 即 a 的别名,函数内修改 x 等价于修改 a,故 a 变为 10。
登录后查看内容
此内容需要登录后才能查看,请先登录您的账户。
1级权限
需要 1 级或以上权限4. 运行下面代码,屏幕上输出是()。
cpp
double* p_arr = new double[3];
p_arr[0] = 0.2;
p_arr[1] = 0.5;
p_arr[2] = 0.8;
p_arr += 1; // 指针后移一位
cout << p_arr[0] << endl;
delete[] p_arr - 1; // 恢复原地址再释放1
2
3
4
5
6
7
2
3
4
5
6
7
A. 0.2
B. 0.5
C. 1.2
D. 1.5
查看解析
答案:B
考纲知识点: 指针算术
解析: p_arr += 1 指向原数组第二个元素,输出 p_arr[0] 即 0.5。
登录后查看内容
此内容需要登录后才能查看,请先登录您的账户。
1级权限
需要 1 级或以上权限5. 运行下面代码片段后,x 和 *p 的结果分别是()。
cpp
int x = 20;
int* p = &x;
*p = *p + 2;1
2
3
2
3
A. 20 20
B. 20 22
C. 22 20
D. 22 22
查看解析
答案:D
考纲知识点: 指针与变量关系
解析: p 指向 x,*p += 2 修改 x 为 22,故 x 和 *p 均为 22。
登录后查看内容
此内容需要登录后才能查看,请先登录您的账户。
1级权限
需要 1 级或以上权限6. 下面的描述中,()不能正确定义一个名为 Student 的结构体以及一个包含 20 个元素的结构体数组。
A.
cpp
struct Student {
string name;
int age;
float score;
};
struct Student students[20];1
2
3
4
5
6
2
3
4
5
6
B.
cpp
struct Student {
string name;
int age;
float score;
};
Student students[20];1
2
3
4
5
6
2
3
4
5
6
C.
cpp
struct Student {
string name;
int age;
float score;
};
Student* students = new Student[20];1
2
3
4
5
6
2
3
4
5
6
D.
cpp
struct Student {
string name;
int age;
float score;
};
Student students = new Student[20];1
2
3
4
5
6
2
3
4
5
6
查看解析
答案:D
考纲知识点: 结构体数组定义
解析: D 把 new Student[20] 返回的指针赋给普通对象 students,类型不匹配,非法。
登录后查看内容
此内容需要登录后才能查看,请先登录您的账户。
1级权限
需要 1 级或以上权限7. 假定整型是 32 位,对一个 2 行 3 列的二维整数数组 array,假设数组首地址为 0x7ffee4065820,则 &array[1][1] 的地址为()。
A. 0x7ffee4065824
B. 0x7ffee4065828
C. 0x7ffee406582c
D. 0x7ffee4065830
查看解析
答案:D
考纲知识点: 二维数组地址计算
解析: 每个 int 占 4 字节,array[1][1] 位于 1*3 + 1 = 4 个 int 后,偏移 16 字节,地址为 0x...30。
登录后查看内容
此内容需要登录后才能查看,请先登录您的账户。
1级权限
需要 1 级或以上权限8. 下面()正确定义二维数组。
A. int a[3][];
B. int a[][];
C. int a[][4];
D. int a[][2] = {{1,2}},{{1,2}},{{3,4}};
查看解析
答案:D
考纲知识点: 二维数组定义
解析: 二维数组定义时至少第二维大小需确定,且初始化列表合法,只有 D 符合。
登录后查看内容
此内容需要登录后才能查看,请先登录您的账户。
1级权限
需要 1 级或以上权限9. 下面代码采用递推算法来计算斐波那契数列,则横线上应填写()。
cpp
int fib(int n){
if (n == 0 || n == 1)
return n;
int f1 = 0, f2 = 1, result;
for (int i = 2; i <= n; ++i){
// 在此处填入代码
}
return result;
}1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
A.
cpp
result = f1 + f2;
f1 = f2;
f2 = result;1
2
3
2
3
B.
cpp
result += f1 + f2;
f1 = f2;
f2 = result;1
2
3
2
3
C.
cpp
result += f1 + f2;
f2 = result;
f1 = f2;1
2
3
2
3
D.
cpp
result = f1 + f2;
f2 = result;
f1 = f2;1
2
3
2
3
查看解析
答案:A
考纲知识点: 递推实现
解析: 每次迭代需先计算 result = f1 + f2,再向前滑动 f1、f2 指针,A 顺序正确。
登录后查看内容
此内容需要登录后才能查看,请先登录您的账户。
1级权限
需要 1 级或以上权限10. 下面关于排序算法的描述中,不正确的是()。
A. 冒泡排序基于元素交换实现,需借助临时变量,共涉及 3 个单元操作;而插入排序基于元素赋值实现,仅需 1 个单元操作。因此冒泡排序的计算开销通常比插入排序更高。
B. 选择排序在任何情况下的时间复杂度都为 O(n²)。
C. 冒泡排序在任何情况下的时间复杂度都为 O(n²)。
D. 如果给定数据部分有序,插入排序通常比选择排序效率更高。
查看解析
答案:C
考纲知识点: 排序复杂度
解析: 冒泡排序在已排序时最优复杂度为 O(n),故“任何情况下都为 O(n²)”错误。
登录后查看内容
此内容需要登录后才能查看,请先登录您的账户。
1级权限
需要 1 级或以上权限11. 冒泡排序第一轮对数组 {4,1,3,1,5,2} 执行后结果为()。
A. 1,4,3,1,5,2
B. 1,3,1,4,2,5
C. 1,4,3,1,2,5
D. 4,1,3,1,5,2
查看解析
答案:B
考纲知识点: 冒泡排序过程
解析: 第一轮依次比较相邻元素把最大值 5 移到末尾,得到 1,3,1,4,2,5。
登录后查看内容
此内容需要登录后才能查看,请先登录您的账户。
1级权限
需要 1 级或以上权限12. 给定递归代码,其时间复杂度为()。
cpp
int cellRecur(int n){
if (n == 1) return 1;
return cellRecur(n - 1) + cellRecur(n - 1) + 1;
}1
2
3
4
2
3
4
A. O(n²)
B. O(2ⁿ)
C. O(1)
D. O(n)
查看解析
答案:B
考纲知识点: 递归复杂度
解析: 每次产生 2 个子问题,递归树节点数约 2ⁿ,故为指数级 O(2ⁿ)。
登录后查看内容
此内容需要登录后才能查看,请先登录您的账户。
1级权限
需要 1 级或以上权限13. 下面代码实现插入排序,横线上应填写()。
cpp
void insertion_sort(vector<int> &nums){
for (int i = 1; i < nums.size(); ++i){
/* 在此处填入代码 */
while (j >= 0 && nums[j] > base){
nums[j + 1] = nums[j];
--j;
}
nums[j + 1] = base;
}
}1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
A. int base = nums[i], j = i - 1;
B. int base = nums[i], j = 1;
C. int base = nums[0], j = i - 1;
D. int base = nums[0], j = i;
查看解析
答案:A
考纲知识点: 插入排序实现
解析: 需将当前元素 nums[i] 保存为 base,并用 j 从 i-1 向左扫描,A 符合。
登录后查看内容
此内容需要登录后才能查看,请先登录您的账户。
1级权限
需要 1 级或以上权限已按规范重新构建 第14题 完整题目与解析如下:
14. 下面哪种方式不能实现将字符串 "Welcome to GESP!" 输出重定向到文件 log.txt( )。
A.
cpp
freopen("log.txt", "w", stdout);
cout << "Welcome to GESP!" << endl;
fclose(stdout);1
2
3
2
3
B.
cpp
std::ofstream outFile("log.txt");
outFile << "Welcome to GESP!" << endl;
outFile.close();1
2
3
2
3
C.
cpp
std::ofstream outFile("log.txt");
cout << "Welcome to GESP!" << endl;
outFile.close();1
2
3
2
3
D.
cpp
ofstream log_file("log.txt");
streambuf* org_cout = cout.rdbuf();
cout.rdbuf(log_file.rdbuf());
cout << "Welcome to GESP!" << endl;
cout.rdbuf(org_cout);1
2
3
4
5
2
3
4
5
查看解析
答案:C
考纲知识点: C++ 文件重定向与流
解析:
- A 使用
freopen将标准输出重定向到文件; - B 直接通过
ofstream写入文件; - D 通过
rdbuf替换cout的缓冲区实现重定向; - C 虽然创建了
ofstream,但cout并未被关联到该文件,输出仍定向到屏幕,无法写入文件,因此 C 不能实现重定向。
登录后查看内容
此内容需要登录后才能查看,请先登录您的账户。
1级权限
需要 1 级或以上权限15. 运行下面代码将出现什么情况?
cpp
double hmean(double a, double b){
if (a == -b)
throw runtime_error("Runtime error occurred");
return 2.0 * a * b / (a + b);
}
int main(){
double x = 10, y = -10;
try{
int result = hmean(x, y);
cout << "hmean: " << result << endl;
}catch (const runtime_error& e){
cout << "Caught: " << e.what() << endl;
}catch (...){
cout << "Caught an unknown exception." << endl;
}
return 0;
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
A. 屏幕上输出 Caught: Runtime error occurred
B. 屏幕上输出 Caught an unknown exception
C. 程序调用 std::terminate
D. 编译错误
查看解析
答案:A
考纲知识点: 异常处理
解析: a == -b 成立,抛出 runtime_error,被第一个 catch 捕获输出指定信息。
登录后查看内容
此内容需要登录后才能查看,请先登录您的账户。
1级权限
需要 1 级或以上权限二、判断题(每题2分,共20分)
判断题答案
| 题号 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
|---|---|---|---|---|---|---|---|---|---|---|
| 答案 | × | × | × | × | √ | √ | √ | √ | × | × |
登录后查看内容
此内容需要登录后才能查看,请先登录您的账户。
1级权限
需要 1 级或以上权限1. 在 C++ 中,下面代码可以正确定义指针和初始化指针。
cpp
int* ptr;
*ptr = 10;1
2
2
查看解析
答案:×
考纲知识点: 指针初始化
解析: ptr 未指向有效内存就解引用赋值,行为未定义,应先 int* ptr = new int; *ptr = 10;。
登录后查看内容
此内容需要登录后才能查看,请先登录您的账户。
1级权限
需要 1 级或以上权限2. 一个函数必须在调用之前既声明又定义。
查看解析
答案:×
考纲知识点: 函数声明与定义
解析: 只需提前声明即可调用,定义可放在后面;声明与定义不必同时。
登录后查看内容
此内容需要登录后才能查看,请先登录您的账户。
1级权限
需要 1 级或以上权限3. 函数参数可以通过值传递、引用传递和指针传递,这样函数内对参数的修改可以直接修改传入变量的值。
查看解析
答案:×
考纲知识点: 参数传递方式
解析: 引用和指针传递可直接修改原变量,值传递则不会。
登录后查看内容
此内容需要登录后才能查看,请先登录您的账户。
1级权限
需要 1 级或以上权限4. int arr[3][] 是一个正确的二维数组的声明。
查看解析
答案:×
考纲知识点: 二维数组语法
解析: 第二维大小必须给出,正确写法如 int arr[3][4];。
登录后查看内容
此内容需要登录后才能查看,请先登录您的账户。
1级权限
需要 1 级或以上权限5. 递推是一种通过已知的初始值和递推公式,逐步求解目标值的算法。
查看解析
答案:√
考纲知识点: 递推概念
解析: 描述准确,递推利用已知状态逐步推导未知状态。
登录后查看内容
此内容需要登录后才能查看,请先登录您的账户。
1级权限
需要 1 级或以上权限6. 某算法的递推关系式为 T(n) = T(n-1) + n 及 T(0) = 1,则该算法的时间复杂度为 O(n²)。
查看解析
答案:√
考纲知识点: 递推复杂度分析
解析: 展开得 T(n)=1+2+…+n 累加和,O(n²)。
登录后查看内容
此内容需要登录后才能查看,请先登录您的账户。
1级权限
需要 1 级或以上权限7. 冒泡排序的平均时间复杂度为 O(n²),但最优情况下为 O(n)。
查看解析
答案:√
考纲知识点: 冒泡排序复杂度
解析: 已排序时无交换,加标志位可做到 O(n)。
登录后查看内容
此内容需要登录后才能查看,请先登录您的账户。
1级权限
需要 1 级或以上权限8. 冒泡排序和插入排序都是稳定的排序算法。
查看解析
答案:√
考纲知识点: 排序稳定性
解析: 两者不改变相同元素的相对顺序,均为稳定排序。
登录后查看内容
此内容需要登录后才能查看,请先登录您的账户。
1级权限
需要 1 级或以上权限9. 选择排序是稳定的排序算法。
查看解析
答案:×
考纲知识点: 选择排序稳定性
解析: 选择排序交换非相邻元素,可能破坏相同键值相对次序,不稳定。
登录后查看内容
此内容需要登录后才能查看,请先登录您的账户。
1级权限
需要 1 级或以上权限10. 在 C++ 中,如果一个函数可能抛出异常,那么一定要在 try 子句里调用这个函数。
查看解析
答案:×
考纲知识点: 异常机制
解析: 异常可以向上传播,未捕获时由调用者或 std::terminate 处理,不强制必须 try 内调用。
登录后查看内容
此内容需要登录后才能查看,请先登录您的账户。
1级权限
需要 1 级或以上权限三、编程题(每题25分,共50分)
1. Recaman
题目描述
小杨最近发现了有趣的 Recaman 数列,这个数列是这样生成的:
- 数列的第一项
a₁是 1; - 如果
aₖ₋₁ − k是正整数并且没有在数列中出现过,那么数列的第k项aₖ为aₖ₋₁ − k,否则为aₖ₋₁ + k; - 小杨想知道 Recaman 数列的前
n项从小到大排序后的结果。手动计算非常困难,小杨希望你能帮他解决这个问题。
输入格式
第一行,一个正整数 n。
输出格式
一行,n 个空格分隔的整数,表示 Recaman 数列的前 n 项从小到大排序后的结果。
输入样例1
text
51
输出样例1
text
1 2 3 6 71
输入样例2
text
121
输出样例2
text
1 2 3 6 7 12 13 201
样例解释
对于样例1,n = 5:
- a₁ = 1;
- a₁ − 2 = −1 不是正整数,因此 a₂ = a₁ + 2 = 3;
- a₂ − 3 = 0 不是正整数,因此 a₃ = a₂ + 3 = 6;
- a₃ − 4 = 2 是正整数且未出现过,因此 a₄ = 2;
- a₄ − 5 = −3 不是正整数,因此 a₅ = a₄ + 5 = 7;
- 将 a₁, a₂, a₃, a₄, a₅ 从小到大排序后的结果为 1 2 3 6 7。
数据范围
对于所有数据点,保证 1 ≤ n ≤ 3000。
解题思路
查看解题思路
考纲知识点:
递推、哈希判重、排序
简化题意:
按规则生成 Recaman 序列前 n 项,升序后输出。
解题思路:
- 用布尔数组
vis记录已出现数值。 - 递推生成
a[i]:判断a[i-1]-i是否合法;合法则取减,否则取加。 - 标记已出现数值。
- 用冒泡排序或
sort排序后输出。
登录后查看内容
此内容需要登录后才能查看,请先登录您的账户。
1级权限
需要 1 级或以上权限参考程序
查看参考程序
cpp
#include <cstdio>
#include <algorithm>
using namespace std;
const int N = 3005;
const int C = 1e6 + 5;
int n;
int a[N];
int vis[C];
void bubble_sort(int *a, int n) {
bool flag = true;
while (flag) {
flag = false;
for (int i = 1; i < n; ++i) {
if (a[i] > a[i + 1]) {
int t = a[i];
a[i] = a[i + 1];
a[i + 1] = t;
flag = true;
}
}
}
}
int main() {
scanf("%d", &n);
a[1] = 1;
vis[1] = 1;
for (int i = 2; i <= n; ++i) {
int prev = a[i - 1] - i;
if (prev > 0 && !vis[prev]) {
a[i] = prev;
} else {
a[i] = a[i - 1] + i;
}
vis[a[i]] = 1;
}
bubble_sort(a, n);
for (int i = 1; i <= n; ++i)
printf("%d%c", a[i], " \n"[i == n]);
return 0;
}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
41
42
43
44
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
41
42
43
44
登录后查看内容
此内容需要登录后才能查看,请先登录您的账户。
1级权限
需要 1 级或以上权限2. 字符排序
题目描述
小杨有 n 个仅包含小写字母的字符串 s₁, s₂, …, sₙ。
小杨想将这些字符串按一定顺序排列后拼接到一起构成字符串 t,并满足:
- 对于所有的
j < i,均有tⱼ ≤ tᵢ(字典序非降)。
小杨想知道是否存在满足条件的字符串排列顺序。
输入格式
第一行包含一个正整数 T,代表测试数据组数。
对于每组测试数据,第一行包含一个正整数 n,含义如题面所示。
之后 n 行,每行包含一个字符串 sᵢ。
输出格式
对于每组测试数据,如果存在满足条件的排列顺序,输出 1,否则输出 0。
输入样例1
text
3
3
aa
ac
de
1
abc
2
ba
ab1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
输出样例1
text
1
1
01
2
3
2
3
样例解释
- 第一组可排为
aa ac de→aaacde,满足非降序。 - 第三组无论怎样排列均无法得到非降序字符串,故输出
0。
数据范围
对于全部数据,保证 1 ≤ T, n ≤ 100,每个字符串的长度不超过 10。
解题思路
查看解题思路
考纲知识点: 字符串排序、字典序
简化题意: 判断是否能将所有字符串整体按字典序非降序排列。
解题思路:
- 对所有字符串按字典序升序排序。
- 依次拼接后检查是否整体非降序即可。
登录后查看内容
此内容需要登录后才能查看,请先登录您的账户。
1级权限
需要 1 级或以上权限参考程序
查看参考程序
cpp
#include <bits/stdc++.h>
using namespace std;
const int N = 110;
string s[N];
void bubble_sort(string *a, int n) {
bool flag = true;
while (flag) {
flag = false;
for (int i = 0; i < n - 1; ++i) {
if (a[i] > a[i + 1]) {
swap(a[i], a[i + 1]);
flag = true;
}
}
}
}
int main() {
ios::sync_with_stdio(false);
int T;
cin >> T;
while (T--) {
int n;
cin >> n;
for (int i = 0; i < n; ++i) cin >> s[i];
bubble_sort(s, n);
string t;
for (int i = 0; i < n; ++i) t += s[i];
bool ok = true;
for (int i = 1; i < t.size(); ++i)
if (t[i] < t[i - 1]) {
ok = false;
break;
}
cout << ok << '\n';
}
return 0;
}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
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
登录后查看内容
此内容需要登录后才能查看,请先登录您的账户。
1级权限
需要 1 级或以上权限