GESP 客观题评测系统
2025-12-Level-8
2025-12-Level-8
试卷解析总览,可直接查看每题答案与解析。
第 1 题(单选题)
某平台生成“取件码”由6个字符组成:前4位为数字(0 - 9),后2位为大写字母(A - Z),其中字母不能为 I、O。假设数字和字母均可重复使用,要求整个取件码中恰好有2个数字为奇数。共有多少种不同取件码?( )
正确答案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); // 合并操作
}正确答案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
解析详情
【答案】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 题(单选题)
二项式的展开式中项的系数为()。
正确答案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];
}
}
}正确答案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];
}正确答案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 题(单选题)
已知两个点和在平面直角坐标系中的坐标。下列C++表达式中,能正确计算这两点之间直线距离的是( )。
正确答案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 的值是()。
正确答案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;
}
}正确答案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 题(单选题)
下列程序实现了线性筛法(欧拉筛),用于在时间内求出之间的所有质数。为了保证每个合数只被其最小质因子筛掉,横线处应填入的语句是()。
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; // 在此处填入选项
}
}正确答案C
解析详情
【答案】C
【考点】线性筛;质数筛法;最小质因子
【解析】 线性筛的关键是让每个合数只被它的最小质因子筛掉一次。 当枚举到 primes[j] 时,如果 i % primes[j] == 0,说明 primes[j] 已经是 i 的最小质因子,此时 i * primes[j] 也该在这里停止,后面更大的质数不应再参与当前 i 的筛除。 所以应写 if (i % primes[j] == 0) break;,选 C。
【易错点】 如果不停下来,很多合数会被重复筛到,就不是线性筛了。
第 11 题(单选题)
在 C++ 语言中,关于类的继承和访问权限,下列说法正确的是()。
正确答案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;
}正确答案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
解析详情
【答案】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;
}正确答案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 算法。已按边权从小到大依次扫描到某条边。此时在已经构建的部分 MST 结构中,已在同一连通块内。关于边的处理,下列说法正确的是()。
正确答案B
解析详情
【答案】B
【考点】最小生成树;Kruskal;并查集思想
【解析】 Kruskal 按边权从小到大扫描边。 如果当前边的两个端点已经在同一连通块中,再加入这条边就会形成环,因此这条边不能加入 MST。 所以这条边一定舍弃,选 B。
【易错点】 Kruskal 一旦判断会成环,这条边就直接丢弃,不存在后面再回头改选。
判断题(每题 2 分)
第 1 题(判断题)
若一项任务可用两种互斥方案完成:方案A有m种做法,方案B有n种做法,则总做法数为。
正确答案正确
解析详情
【答案】正确
【考点】加法原理;分类计数
【解析】 任务可以用两种互斥方案完成,说明两类做法之间没有重叠。 方案A有 m 种,方案B有 n 种,总做法数就是 m+n。 所以本题正确。
【易错点】 只有在“两类方案互斥”时,才能直接相加。
第 2 题(判断题)
在C++语言中,引用一旦被初始化,就不能再改为引用另一个变量。
正确答案正确
解析详情
【答案】正确
【考点】引用;C++ 基础语法
【解析】 引用在定义时必须绑定到某个变量,一旦绑定完成,就不能再改成引用别的变量。 后续对引用赋值,是修改它所绑定的那个变量,不是重新绑定。 所以本题正确。
【易错点】 “给引用赋值”和“让引用改绑到别处”是两回事。
第 3 题(判断题)
快速排序和归并排序的平均时间复杂度都是,但快速排序是不稳定的排序算法,归并排序是稳定的排序算法。
正确答案正确
解析详情
【答案】正确
【考点】排序算法;时间复杂度;稳定性
【解析】 快速排序和归并排序的平均时间复杂度都为 O(n log n)。 快速排序通常是不稳定排序,归并排序是稳定排序。 这两个判断都对,所以本题正确。
【易错点】 稳定性考查的是相等元素的相对顺序是否保持。
第 4 题(判断题)
使用 math.h 或 cmath 头文件中的函数,表达式 sqrt(4) 的结果类型为 double。
正确答案正确
解析详情
【答案】正确
【考点】数学函数;返回值类型;C++ 标准库
【解析】 sqrt 在 cmath 中返回浮点结果,表达式 sqrt(4) 的结果类型是 double。 即使参数写成整数,返回值也不是整型。 所以本题正确。
【易错点】 参数是整数,不代表返回值也是整数。
第 5 题(判断题)
在杨辉三角形中,第 n 行(从0开始计数,即第 n 行有个数)的所有数字之和等于。
正确答案正确
解析详情
【答案】正确
【考点】杨辉三角;二项式定理
【解析】 杨辉三角第 n 行各项系数之和,等于 (1+1)^n = 2^n。 题目已经说明行号从0开始计数,因此第 n 行所有数字之和就是 2^n。 所以本题正确。
【易错点】 不要把“第 n 行”与“有 n 个数”的版本混淆,题目这里是有 n+1 个数。
第 6 题(判断题)
使用二叉堆优化的Dijkstra最短路算法,在某些特殊情况下时间复杂度不如朴素实现的。
正确答案正确
解析详情
【答案】正确
【考点】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 题(判断题)
快速排序在最坏情况下的时间复杂度为,可以通过随机化选择基准值(pivot)的方法完全避免退化。
正确答案错误
解析详情
【答案】错误
【考点】快速排序;最坏复杂度;随机化
【解析】 快速排序最坏情况下的时间复杂度是 O(n^2),不是 O(n log n)。 随机化选 pivot 只能降低退化概率,不能彻底保证永不退化。 所以题目两处说法都不对,本题错误。
【易错点】 “随机化能改善平均表现”不等于“能完全消除最坏情况”。
第 9 题(判断题)
在C++语言中,一个类可以拥有多个构造函数,也可以拥有多个析构函数。
正确答案错误
解析详情
【答案】错误
【考点】构造函数;析构函数;函数重载
【解析】 一个类可以有多个构造函数,因为构造函数可以重载。 但析构函数不能重载,一个类只能有一个析构函数。 所以题目后半句错误,本题错误。
【易错点】 构造函数能重载,析构函数不能重载,这是常见考点。
第 10 题(判断题)
求两个序列的最长公共子序列(LCS)时,使用滚动数组优化空间后,仍然可以还原出具体的LCS序列。
正确答案错误
解析详情
【答案】错误
【考点】最长公共子序列;动态规划;空间优化
【解析】 滚动数组只保留少量行或列,能算出 LCS 长度,但会丢失很多中间状态。 如果不额外保存转移信息,通常无法直接还原出完整的 LCS 序列。 所以题目中的说法不成立,本题错误。
【易错点】 “能求长度”和“能还原具体方案”是两个不同层次的问题。