GESP 客观题评测系统

2025-12-Level-8

2025-12-Level-8

试卷解析总览,可直接查看每题答案与解析。

单选题(每题 2 分)

1 题(单选题

某平台生成“取件码”由6个字符组成:前4位为数字(0 - 9),后2位为大写字母(A - Z),其中字母不能为 I、O。假设数字和字母均可重复使用,要求整个取件码中恰好有2个数字为奇数。共有多少种不同取件码?( )

A.
1,440,000
B.
2,160,000
C.
2,535,000
D.
8,640,000

正确答案B

解析详情

【答案】B

【考点】分类计数;组合计数;乘法原理

【解析】 前 4 位数字中恰好有 2 位奇数,先从 4 个位置里选出 2 个放奇数,有 C(4,2)=6 种。 每个奇数位有 5 种填法,每个偶数位也有 5 种填法,所以前 4 位共有 6 × 5^2 × 5^2 = 3750 种。 后 2 位是大写字母,且不能为 I、O,因此每位有 24 种选择,两位共有 24^2 = 576 种。 总数是 3750 × 576 = 2160000,所以选 B。

【易错点】 容易只统计前 4 位里奇数的位置,却漏掉偶数位也各有 5 种可选数字。

2 题(单选题

下列代码实现了归并排序(Merge Sort)的分治部分。为了正确地将数组 a 的 [left, right] 区间进行排序,横线处应该填入的是()。

void merge_sort(int a[], int left, int right) {
    if (left >= right) return;
    int mid = (left + right) / 2;
    merge_sort(a, left, mid);
    ___; // 在此处填入选项
    merge(a, left, mid, right); // 合并操作
}
A.
merge_sort(a, mid, right)
B.
merge_sort(a, mid + 1, right)
C.
merge_sort(a, left, mid + 1)
D.
merge_sort(a, mid - 1, right)

正确答案B

解析详情

【答案】B

【考点】归并排序;分治;递归区间

【解析】 归并排序把区间 [left, right] 分成左半段 [left, mid] 和右半段 [mid+1, right],分别排好序后再合并。 前一行已经递归处理了左半段,所以横线处应递归处理右半段,即 merge_sort(a, mid + 1, right)。 因此选 B。

【易错点】 容易把右半段写成 [mid, right],这样会让 mid 被重复处理。

3 题(单选题

某社团有男生8人、女生7人。现需选出1名队长(性别不限)、1名副队长(性别不限)、2名宣传委员(两人无角色区别,且必须至少1名女生)。假如一人不能兼任多职,共有多少种不同选法?()

A.
12012
B.
11844
C.
12474
D.
11025

正确答案A

解析详情

【答案】A

【考点】排列组合;分类讨论;限制条件计数

【解析】 先选队长和副队长,这两个职务有先后顺序;再从剩余人中选2名宣传委员,宣传委员没有顺序,且至少1名女生。 分三类讨论队长和副队长的性别。两人都是男生时,有 8×7 种,剩下7女6男,宣传委员有 C(13,2)-C(6,2)=63 种。 一男一女时,有 8×7×2 种,剩下6女7男,宣传委员有 C(13,2)-C(7,2)=57 种;两人都是女生时,有 7×6 种,剩下5女8男,宣传委员有 C(13,2)-C(8,2)=50 种。 总数是 8×7×63 + 8×7×2×57 + 7×6×50 = 12012,选 A。

【易错点】 容易把队长和副队长当成无顺序,也容易忘记宣传委员“至少1名女生”的限制。

4 题(单选题

二项式(2xy)8(2x - y)^8的展开式中x5y3x^5 y^3项的系数为()。

A.
-7168
B.
7168
C.
-1792
D.
1792

正确答案C

解析详情

【答案】C

【考点】二项式定理;项的系数

【解析】 在 (2x-y)^8 的展开式中,若要得到 x^5y^3,就要从8个因子里选3个取 -y,其余5个取 2x。 系数为 C(8,3) × 2^5 × (-1)^3 = 56 × 32 × (-1) = -1792。 所以选 C。

【易错点】 容易漏掉 (-y)^3 里的负号。

5 题(单选题

下面是使用邻接矩阵实现 Dijkstra 算法的核心片段,用于求单源最短路径。在找到当前距离起点最近的顶点 u 后,需要更新其邻接点 j 的距离。横线处应填入的代码是()。

for (int j = 1; j <= n; j++) {
    if (!visited[j] && graph[u][j] < INF) {
        if (_____) { // 在此处填入选项
            dis[j] = dis[u] + graph[u][j];
        }
    }
}
A.
dis[j] < dis[u] + graph[u][j]
B.
dis[j] > dis[u] + graph[u][j]
C.
graph[u][j] > dis[u] + dis[j]
D.
dis[j] > graph[u][j]

正确答案B

解析详情

【答案】B

【考点】Dijkstra;最短路;松弛操作

【解析】 Dijkstra 更新邻点时,要比较原来的最短距离和经过 u 中转后的新距离。 如果 dis[u] + graph[u][j] 更小,就更新 dis[j]。 因此判断条件应为 dis[j] > dis[u] + graph[u][j],选 B。

【易错点】 方向很容易写反。更新条件一定是“新路更短”。

6 题(单选题

下面程序使用动态规划求两个字符串的最长公共子序列(LCS)长度,横线处应填入的是()。

#include <algorithm>
#include <string>
#include <vector>
using namespace std;

int lcs_len(const string &a, const string &b) {
    int n = (int)a.size(), m = (int)b.size();
    vector<vector<int>> dp(n + 1, vector<int>(m + 1, 0));
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= m; j++)
            if (a[i - 1] == b[j - 1])
                dp[i][j] = dp[i - 1][j - 1] + 1;
            else
                // 在此处填入选项
    return dp[n][m];
}
A.
dp[i][j] = dp[i - 1][j] + dp[i][j - 1];
B.
dp[i][j] = min(dp[i - 1][j], dp[i][j - 1]);
C.
dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]);
D.
dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]) + 1;

正确答案C

解析详情

【答案】C

【考点】动态规划;最长公共子序列;状态转移

【解析】 LCS 中,当 a[i-1] == b[j-1] 时,dp[i][j] = dp[i-1][j-1] + 1。 当两个字符不相等时,当前位置不能同时选这两个字符,只能舍去其中一个,所以取 max(dp[i-1][j], dp[i][j-1])。 因此选 C。

【易错点】 容易把不相等时也写成加1,那就变成错误转移了。

7 题(单选题

已知两个点A(x1,y1)A(x_1, y_1)B(x2,y2)B(x_2, y_2)在平面直角坐标系中的坐标。下列C++表达式中,能正确计算这两点之间直线距离的是( )。

A.
sqrt((x1 - x2) ^ 2 + (y1 - y2) ^ 2)
B.
sqrt(pow(x1 - x2, 2) + pow(y1 - y2, 2))
C.
pow(x1 - x2, 2) + pow(y1 - y2, 2)
D.
abs(x1 - x2) + abs(y1 - y2)

正确答案B

解析详情

【答案】B

【考点】平面坐标;距离公式;C++ 表达式

【解析】 平面上两点 A(x1,y1)、B(x2,y2) 的距离公式是 sqrt((x1-x2)^2 + (y1-y2)^2)。 在 C++ 中不能直接用 ^2 表示平方,因为 ^ 是按位异或,不是乘方。 四个选项里,只有 sqrt(pow(x1 - x2, 2) + pow(y1 - y2, 2)) 正确表达了距离公式,所以选 B。

【易错点】 最容易错在把 ^ 当成乘方运算符。

8 题(单选题

已知 int a = 10;,执行 int &b = a; b = 20; 后,变量 a 的值是()。

A.
10
B.
20
C.
30
D.
编译错误

正确答案B

解析详情

【答案】B

【考点】引用;变量别名;赋值

【解析】 int &b = a 表示 b 是 a 的引用,也就是 a 的别名。 给 b 赋值 20,本质上就是给 a 赋值 20。 所以执行后 a=20,选 B。

【易错点】 引用不是复制出一个新变量,而是给原变量起了一个别名。

9 题(单选题

下列代码的时间复杂度(以n为自变量,忽略常数与低阶项)是()。

long long s = 0;
for (int i = 1; i <= n; i++) {
    for (int j = 1; j * j <= i; j++) {
        s += j;
    }
}
A.
O(n)O(n)
B.
O(nlogn)O(n \log n)
C.
O(nn)O(n \sqrt{n})
D.
O(n2)O(n^{2})

正确答案C

解析详情

【答案】C

【考点】时间复杂度;循环分析;求和估计

【解析】 外层循环执行 n 次。 当固定 i 时,内层循环条件是 j*j <= i,所以 j 大约跑到 sqrt(i),内层复杂度是 O(sqrt(i))。 总复杂度为 sum_{i=1}^{n} O(sqrt(i)) = O(n sqrt(n)),因此选 C。

【易错点】 不能只看成两层循环就直接写成 O(n^2),关键要看内层到底跑多少次。

10 题(单选题

下列程序实现了线性筛法(欧拉筛),用于在O(n)O(n)时间内求出1n1 \sim n之间的所有质数。为了保证每个合数只被其最小质因子筛掉,横线处应填入的语句是()。

for (int i = 2; i <= n; i++) {
    if (!not_prime[i]) primes[++cnt] = i;
    for (int j = 1; j <= cnt && i * primes[j] <= n; j++) {
        not_prime[i * primes[j]] = true;
        if (_____) break; // 在此处填入选项
    }
}
A.
i + primes[j] == n
B.
primes[j] > i
C.
i % primes[j] == 0
D.
i % primes[j] != 0

正确答案C

解析详情

【答案】C

【考点】线性筛;质数筛法;最小质因子

【解析】 线性筛的关键是让每个合数只被它的最小质因子筛掉一次。 当枚举到 primes[j] 时,如果 i % primes[j] == 0,说明 primes[j] 已经是 i 的最小质因子,此时 i * primes[j] 也该在这里停止,后面更大的质数不应再参与当前 i 的筛除。 所以应写 if (i % primes[j] == 0) break;,选 C。

【易错点】 如果不停下来,很多合数会被重复筛到,就不是线性筛了。

11 题(单选题

在 C++ 语言中,关于类的继承和访问权限,下列说法正确的是()。

A.
派生类可以访问基类的 private 成员。
B.
基类的 protected 成员在私有继承(private inheritance)后,在派生类中变为 public 。
C.
派生类对象在创建时,会先调用基类的构造函数,再调用派生类自己的构造函数。
D.
派生类对象在销毁时,会先调用基类的析构函数,再调用派生类自己的析构函数。

正确答案C

解析详情

【答案】C

【考点】类与对象;继承;构造与析构

【解析】 派生类对象创建时,必须先把基类部分构造好,再构造派生类自身,所以先调用基类构造函数,再调用派生类构造函数。 A 错在 private 成员不能被派生类直接访问。B 错在 private 继承后,基类的 public 和 protected 成员在派生类中都变成 private,不会变成 public。 D 错在析构顺序相反,应该先析构派生类,再析构基类。所以选 C。

【易错点】 构造顺序和析构顺序正好相反,最容易混淆。

12 题(单选题

当输入 6 时,下列程序的输出结果为()。

#include <iostream>
using namespace std;
int f(int n) {
    if (n <= 3) return n;
    return f(n - 1) + f(n - 2) + 2 * f(n - 3);
}
int main() {
    int n;
    cin >> n;
    cout << f(n) << endl;
    return 0;
}
A.
14
B.
27
C.
28
D.
15

正确答案B

解析详情

【答案】B

【考点】递归;递推;函数求值

【解析】 由题意可得 f(1)=1,f(2)=2,f(3)=3。 继续往后算:f(4)=f(3)+f(2)+2f(1)=3+2+2=7,f(5)=f(4)+f(3)+2f(2)=7+3+4=14,f(6)=f(5)+f(4)+2f(3)=14+7+6=27。 所以输出 27,选 B。

【易错点】 容易把 2 * f(n-3) 漏乘2。

13 题(单选题

从 1 到 999 这 999 个正整数中,十进制表示中数字 5 恰好出现一次的数有多少个?()

A.
243
B.
271
C.
300
D.
333

正确答案A

解析详情

【答案】A

【考点】计数原理;分类计数;数位问题

【解析】 把 1 到 999 看成3位数,不足3位的前面补0。 要求数字5恰好出现一次。先选哪一位是5,有3种选法;其余两位都不能是5,每位各有9种选法。 所以总数为 3 × 9 × 9 = 243,选 A。补零不会带来问题,因为 000 本身不含数字5,不会被算进去。

【易错点】 很多人会把一位数、两位数、三位数拆开分类,其实补零后统一处理更快。

14 题(单选题

当输入 2023 时,下列程序的输出结果为()。

#include <iostream>
using namespace std;

int main() {
    int x, ans = 0;
    cin >> x;
    while (x != 0) {
        x -= x & -x;
        ans++;
    }
    cout << ans << endl;
    return 0;
}
A.
7
B.
8
C.
9
D.
11

正确答案C

解析详情

【答案】C

【考点】二进制;lowbit;位运算

【解析】 表达式 x & -x 会取出 x 的最低位1。 循环中每次执行 x -= x & -x,就是把 x 的二进制表示中最低位的一个1消掉,因此循环次数等于二进制里1的个数。 2023 = 1024+512+256+128+64+32+4+2+1,共9个1,所以输出9,选 C。

【易错点】 这段程序不是求二进制位数,而是求二进制中1的个数。

15 题(单选题

对连通无向图执行 Kruskal 算法。已按边权从小到大依次扫描到某条边e=(u,v)e = (u, v)。此时在已经构建的部分 MST 结构中,(u,v)(u, v)已在同一连通块内。关于边ee的处理,下列说法正确的是()。

A.
必须选入 MST,否则可能不连通。
B.
一定不能选入 MST(在此扫描顺序下)。
C.
若后续出现更大的边权,可以回溯改选ee
D.
只有当ee是当前最小边时才能舍弃。

正确答案B

解析详情

【答案】B

【考点】最小生成树;Kruskal;并查集思想

【解析】 Kruskal 按边权从小到大扫描边。 如果当前边的两个端点已经在同一连通块中,再加入这条边就会形成环,因此这条边不能加入 MST。 所以这条边一定舍弃,选 B。

【易错点】 Kruskal 一旦判断会成环,这条边就直接丢弃,不存在后面再回头改选。

判断题(每题 2 分)

1 题(判断题

若一项任务可用两种互斥方案完成:方案A有m种做法,方案B有n种做法,则总做法数为m+nm+n

正确答案正确

解析详情

【答案】正确

【考点】加法原理;分类计数

【解析】 任务可以用两种互斥方案完成,说明两类做法之间没有重叠。 方案A有 m 种,方案B有 n 种,总做法数就是 m+n。 所以本题正确。

【易错点】 只有在“两类方案互斥”时,才能直接相加。

2 题(判断题

在C++语言中,引用一旦被初始化,就不能再改为引用另一个变量。

正确答案正确

解析详情

【答案】正确

【考点】引用;C++ 基础语法

【解析】 引用在定义时必须绑定到某个变量,一旦绑定完成,就不能再改成引用别的变量。 后续对引用赋值,是修改它所绑定的那个变量,不是重新绑定。 所以本题正确。

【易错点】 “给引用赋值”和“让引用改绑到别处”是两回事。

3 题(判断题

快速排序和归并排序的平均时间复杂度都是O(nlogn)O(n \log n),但快速排序是不稳定的排序算法,归并排序是稳定的排序算法。

正确答案正确

解析详情

【答案】正确

【考点】排序算法;时间复杂度;稳定性

【解析】 快速排序和归并排序的平均时间复杂度都为 O(n log n)。 快速排序通常是不稳定排序,归并排序是稳定排序。 这两个判断都对,所以本题正确。

【易错点】 稳定性考查的是相等元素的相对顺序是否保持。

4 题(判断题

使用 math.h 或 cmath 头文件中的函数,表达式 sqrt(4) 的结果类型为 double。

正确答案正确

解析详情

【答案】正确

【考点】数学函数;返回值类型;C++ 标准库

【解析】 sqrt 在 cmath 中返回浮点结果,表达式 sqrt(4) 的结果类型是 double。 即使参数写成整数,返回值也不是整型。 所以本题正确。

【易错点】 参数是整数,不代表返回值也是整数。

5 题(判断题

在杨辉三角形中,第 n 行(从0开始计数,即第 n 行有n+1n+1个数)的所有数字之和等于2n2^{n}

正确答案正确

解析详情

【答案】正确

【考点】杨辉三角;二项式定理

【解析】 杨辉三角第 n 行各项系数之和,等于 (1+1)^n = 2^n。 题目已经说明行号从0开始计数,因此第 n 行所有数字之和就是 2^n。 所以本题正确。

【易错点】 不要把“第 n 行”与“有 n 个数”的版本混淆,题目这里是有 n+1 个数。

6 题(判断题

使用二叉堆优化的Dijkstra最短路算法,在某些特殊情况下时间复杂度不如朴素实现的O(V2)O(V^{2})

正确答案正确

解析详情

【答案】正确

【考点】Dijkstra;复杂度比较;图的稠密与稀疏

【解析】 朴素 Dijkstra 的复杂度是 O(V^2),二叉堆优化后通常是 O((V+E)logV)。 在稠密图中,E 接近 V^2,这时 O((V+E)logV) 可能比 O(V^2) 更差。 所以题目说“某些特殊情况下时间复杂度不如朴素实现”是正确的。

【易错点】 堆优化不是任何情况下都更快,要看图的边数规模。

7 题(判断题

n 个不同元素依次入栈的出栈序列数与将 n 个不同元素划分成若干非空子集的方案数相等。

正确答案错误

解析详情

【答案】错误

【考点】Catalan 数;Bell 数;组合计数

【解析】 n 个不同元素依次入栈的合法出栈序列个数是 Catalan 数。 把 n 个不同元素划分成若干非空子集的方案数是 Bell 数。 这两个数列不是同一个数列,因此不相等,所以本题错误。

【易错点】 都属于计数问题,但对应的模型完全不同。

8 题(判断题

快速排序在最坏情况下的时间复杂度为O(nlogn)O(n \log n),可以通过随机化选择基准值(pivot)的方法完全避免退化。

正确答案错误

解析详情

【答案】错误

【考点】快速排序;最坏复杂度;随机化

【解析】 快速排序最坏情况下的时间复杂度是 O(n^2),不是 O(n log n)。 随机化选 pivot 只能降低退化概率,不能彻底保证永不退化。 所以题目两处说法都不对,本题错误。

【易错点】 “随机化能改善平均表现”不等于“能完全消除最坏情况”。

9 题(判断题

在C++语言中,一个类可以拥有多个构造函数,也可以拥有多个析构函数。

正确答案错误

解析详情

【答案】错误

【考点】构造函数;析构函数;函数重载

【解析】 一个类可以有多个构造函数,因为构造函数可以重载。 但析构函数不能重载,一个类只能有一个析构函数。 所以题目后半句错误,本题错误。

【易错点】 构造函数能重载,析构函数不能重载,这是常见考点。

10 题(判断题

求两个序列的最长公共子序列(LCS)时,使用滚动数组优化空间后,仍然可以还原出具体的LCS序列。

正确答案错误

解析详情

【答案】错误

【考点】最长公共子序列;动态规划;空间优化

【解析】 滚动数组只保留少量行或列,能算出 LCS 长度,但会丢失很多中间状态。 如果不额外保存转移信息,通常无法直接还原出完整的 LCS 序列。 所以题目中的说法不成立,本题错误。

【易错点】 “能求长度”和“能还原具体方案”是两个不同层次的问题。