GESP 客观题评测系统
2025-06-Level-8
2025-06-Level-8
试卷解析总览,可直接查看每题答案与解析。
第 1 题(单选题)
一间的机房要安排6名同学进行上机考试,座位共2行3列。考虑到在座位上很容易看到同一行的左右两侧的屏幕,安排中间一列的同学做A卷,左右两列的同学做B卷。请问共有多少种排座位的方案?()。
正确答案A
解析详情
【答案】A
【考点】排列计数
【解析】 6个座位中有2个固定是A卷座位、4个固定是B卷座位,但题目并没有限制哪位同学必须做哪种卷,所以本质上只是把6名不同同学安排到6个不同位置。 方案数为 6!=720,因此选 A。
【易错点】 不要把“A卷座位有2个、B卷座位有4个”误当成还要再额外分类选择学生。
第 2 题(单选题)
又到了毕业季,学长学姐们都在开心地拍毕业照。现在有3位学长、3位学姐希望排成一排拍照,要求男生不相邻、女生不相邻。请问共有多少种拍照方案?()。
正确答案B
解析详情
【答案】B
【考点】交错排列
【解析】 男生不相邻且女生不相邻,6个人只能按“男女男女男女”或“女男女男女男”两种性别顺序排。 每种顺序下,3位学长有 3! 种排法,3位学姐也有 3! 种排法,所以总数是 2×3!×3!=72。
【易错点】 先确定性别交错的整体骨架,再分别排列男生和女生,别直接把6人全排列。
第 3 题(单选题)
下列关于C++类和对象的说法,错误的是( )。
正确答案D
解析详情
【答案】D
【考点】C++ 类声明与对象
【解析】 A、B、C 中都定义了一个对象:常量对象 x、string 对象 t、函数指针对象 fp。 而 `class MyClass;` 只是对类名做前向声明,并没有给出类体,所以不能算“定义了一个类”,错误项是 D。
【易错点】 类的声明和类的定义不同,只有带类体的 `class MyClass { ... };` 才是完整定义。
第 4 题(单选题)
关于生成树的说法,错误的是()。
正确答案D
解析详情
【答案】D
【考点】生成树性质
【解析】 A、B 都是生成树的基本性质:连通无向图一定有生成树,生成树一定含 n-1 条边。C 也对,因为一个 n 个点 n-1 条边的无向图若存在生成树,这棵生成树就只能用完全部边,因此不可能有多颗不同生成树。 D 错在遗漏“连通”条件。n个顶点、n-1条边的无向图若不连通,就不是树,更不可能是自己的生成树。
【易错点】 “边数等于 n-1”只是树的必要条件之一,连通性同样必不可少。
第 5 题(单选题)
一对夫妻生男生女的概率相同。这对夫妻希望儿女双全。请问这对夫妻生下两个孩子时,实现儿女双全的概率是多少?()。
正确答案C
解析详情
【答案】C
【考点】古典概型
【解析】 两个孩子的性别等可能结果有 4 种:男男、男女、女男、女女。儿女双全对应“男女”和“女男”两种。 所以概率为 2/4=1/2,对应 C。
【易错点】 “男女”和“女男”是两个不同结果,不能只算成1种。
第 6 题(单选题)
已定义变量 double a, b;,下列哪个表达式可以用来判断一元二次方程是否有实根?()。
正确答案B
解析详情
【答案】B
【考点】一元二次方程判别式
【解析】 方程 x^2+ax+b=0 有实根,当且仅当判别式 Δ=a^2-4b≥0。 把它移项可写成 4*b<=a*a,所以应选 B。A 只覆盖了两实根情形,漏掉重根;C、D 只是数值表达式,不是判断条件。
【易错点】 判断“有实根”要用 ≥0,不是严格大于0。
第 7 题(单选题)
n 个结点的二叉树,执行广度优先搜索的平均时间复杂度是()。
正确答案C
解析详情
【答案】C
【考点】广度优先搜索复杂度
【解析】 在二叉树上做 BFS,每个结点最多入队、出队各一次,并访问其左右孩子常数次。 因此总工作量与结点数 n 成正比,时间复杂度是 O(n),选 C。
【易错点】 树高是 O(log n) 并不代表遍历整棵树也是 O(log n)。
第 8 题(单选题)
以下关于动态规划的说法中,错误的是()。
正确答案B
解析详情
【答案】B
【考点】动态规划复杂度分析
【解析】 A、C、D 都是常见正确表述。B 错在把动态规划复杂度简单说成“状态个数”;实际上还要乘上每个状态的转移代价。 很多题的复杂度应写成“状态数 × 每个状态的转移数”,并不总是只等于状态个数。
【易错点】 DP 的瓶颈不只在状态数量,状态转移方式同样决定复杂度。
第 9 题(单选题)
下面的 sum_digit 函数试图求出从 1 到 n(包含 1 和 n)的数中,包含数字 d 的个数。该函数的时间复杂度为( )。
#include <string>
int count_digit(int n, char d) {
int cnt = 0;
std::string s = std::to_string(n);
for (int i = 0; i < s.length(); i++)
if (s[i] == d)
cnt++;
return cnt;
}
int sum_digit(int n, char d) {
int sum = 0;
for (int i = 1; i <= n; i++)
sum += count_digit(i, d);
return sum;
}正确答案A
解析详情
【答案】A
【考点】字符串处理与复杂度估计
【解析】 外层循环从 1 到 n 共执行 n 次。每次 `count_digit(i,d)` 会把 i 转成字符串并扫描全部位数,代价与 i 的位数成正比,即 O(log n)。 所以总复杂度为 O(n log n),选 A。
【易错点】 不要把 `count_digit` 当成 O(1);数字位数会随 i 增长。
第 10 题(单选题)
下面程序的输出为()。
#include <iostream>
const int N = 10;
int ch[N][N][N];
int main() {
for (int x = 0; x < N; x++)
for (int y = 0; y < N; y++)
for (int z = 0; z < N; z++)
if (x == 0 && y == 0 && z == 0)
ch[x][y][z] = 1;
else {
if (x > 0)
ch[x][y][z] += ch[x - 1][y][z];
if (y > 0)
ch[x][y][z] += ch[x][y - 1][z];
if (z > 0)
ch[x][y][z] += ch[x][y][z - 1];
}
std::cout << ch[1][2][3] << std::endl;
return 0;
}
}正确答案A
解析详情
【答案】A
【考点】动态规划计数与程序输出
【解析】 数组 `ch[x][y][z]` 表示从 (0,0,0) 走到 (x,y,z) 的路径数,每次只能沿三个坐标轴正方向前进,所以状态转移是三个前驱之和。 到达 (1,2,3) 一共要走 1+2+3=6 步,其中三类步分别出现 1、2、3 次,路径数为 6!/(1!2!3!)=60,因此输出 60。
【易错点】 这题虽给了代码,本质是在数不同步序,不是简单相加 1+2+3。
第 11 题(单选题)
下面 count_triple 函数的时间复杂度为()。
int gcd(int a, int b) {
if (a == 0)
return b;
return gcd(b % a, a);
}
int count_triple(int n) {
int cnt = 0;
for (int v = 1; v * v * 4 <= n; v++)
for (int u = v + 1; u * (u + v) * 2 <= n; u += 2)
if (gcd(u, v) == 1) {
int a = u * u - v * v;
int b = u * v * 2;
int c = u * u + v * v;
cnt += n / (a + b + c);
}
return cnt;
}
}正确答案C
解析详情
【答案】C
【考点】循环规模估计与欧几里得算法
【解析】 按题目意图分析,外层枚举 (u,v) 的总次数与 n 同阶;而每次判断 `gcd(u,v)==1` 用欧几里得算法,复杂度是 O(log n)。 因此整体时间复杂度为 O(n log n),对应 C。
【易错点】 两层循环之外还要算上 `gcd` 的代价,不能直接只看成 O(n)。
第 12 题(单选题)
下面 quick_sort 函数试图实现快速排序算法,两处横线处分别应该填入的是()。
void swap(int & a, int & b) {
int temp = a; a = b; b = temp;
}
int partition(int a[], int l, int r) {
int pivot = a[1], i = l + 1, j = r;
while (i <= j) {
while (i <= j && a[j] >= pivot)
j++;
while (i <= j && a[i] <= pivot)
i++;
if (i < j)
swap(a[i], a[j]);
}
// 在此处填入选项
return _____; // 在此处填入选项
}
void quick_sort(int a[], int l, int r) {
if (l < r) {
int pivot = partition(a, l, r);
quick_sort(a, l, pivot - 1);
quick_sort(a, pivot + 1, r);
}
}正确答案D
解析详情
【答案】D
【考点】快速排序划分过程
【解析】 按快速排序的标准划分思路,循环结束后 j 应停在最后一个“小于等于枢轴”的位置,因此应把枢轴与 a[j] 交换,让它落到最终位置。 随后返回的也应是这个最终位置 j,递归才能正确处理左右两段,所以选 D。
【易错点】 分区函数返回值必须和枢轴实际落点一致,否则递归边界会错。
第 13 题(单选题)
下面 LIS 函数试图求出最长上升子序列的长度,横线处应该填入的是()。
int max(int a, int b) {
return (a > b) ? a : b;
}
int LIS(vector<int> & nums) {
int n = nums.size();
if (n == 0)
return 0;
vector<int> dp(n, 1);
int maxLen = 1;
}
for (int i = 1; i < n; i++) {
for (int j = 0; j < i; j++)
if (nums[j] < nums[i])
___; // 在此处填入选项
maxLen = max(maxLen, dp[i]);
}
return maxLen;
}正确答案D
解析详情
【答案】D
【考点】最长上升子序列 DP 转移
【解析】 设 `dp[i]` 表示以 `nums[i]` 结尾的最长上升子序列长度。若 `nums[j] < nums[i]`,就可以把 `nums[i]` 接在以 j 结尾的序列后面,因此转移为 `dp[i] = max(dp[i], dp[j] + 1)`。 这正是选项 D。
【易错点】 更新的是当前结尾位置 `i`,不是前面的 `j`。
第 14 题(单选题)
下面 LIS 函数试图求出最长上升子序列的长度,其时间复杂度为()。
#define INT_MIN (-1000)
int LIS(vector<int> & nums) {
int n = nums.size();
vector<int> tail;
tail.push_back(INT_MIN);
for (int i = 0; i < n; i++) {
int x = nums[i], l = 0, r = tail.size();
while (l < r) {
int mid = (l + r) / 2;
if (tail[mid] < x) {
l = mid + 1;
else {
r = mid;
}
}
if (r == tail.size()) {
tail.push_back(x);
else {
tail[r] = x;
}
}
return tail.size() - 1;
}
}
}正确答案C
解析详情
【答案】C
【考点】LIS 的二分优化
【解析】 外层循环处理每个元素一次,共 n 次;每次都在 `tail` 数组中用二分查找插入或替换位置,代价是 O(log n)。 所以总时间复杂度是 O(n log n),选 C。
【易错点】 二分只优化了单次转移,整体仍要对所有元素各处理一次。
第 15 题(单选题)
下面的程序使用邻接矩阵表达的带权无向图,则从顶点0到顶点3的最短距离为()。
int weight[4][4] = {
{ 0, 5, 8, 10 },
{ 5, 0, 1, 7 },
{ 8, 1, 0, 3 },
{ 10, 7, 3, 0 };
}正确答案A
解析详情
【答案】A
【考点】最短路径计算
【解析】 从 0 到 3 的直接路径长度是 10。经过中间点时,0→1→3 为 5+7=12,0→2→3 为 8+3=11,0→1→2→3 为 5+1+3=9。 最短的是 9,因此选 A。
【易错点】 有直接边并不代表最短,仍要比较经过中间点的路径。
判断题(每题 2 分)
第 1 题(判断题)
C++语言中,表达式 9 | 12 的结果类型为 int、值为 13。
正确答案正确
解析详情
【答案】正确
【考点】按位或运算
【解析】 9 的二进制是 1001,12 的二进制是 1100,按位或后得到 1101,也就是十进制 13。整型字面量参与位运算,结果类型仍是 int。
【易错点】 按位或不是算术加法,要逐位看 0 和 1 的组合结果。
第 2 题(判断题)
C++语言中,访问数据发生下标越界时,总是会产生运行时错误,从而使程序异常退出。
正确答案错误
解析详情
【答案】错误
【考点】数组越界与未定义行为
【解析】 C++ 下标越界通常属于未定义行为,不保证一定触发运行时错误。程序可能崩溃,也可能继续运行但得到垃圾值。
【易错点】 “非法访问”不等于“系统一定会立刻报错”。
第 3 题(判断题)
对n个元素的数组进行归并排序,最差情况的时间复杂度为。
正确答案正确
解析详情
【答案】正确
【考点】归并排序复杂度
【解析】 归并排序每层把数组划分成两半,递归深度约为 log n;每一层归并所有元素的总代价是 O(n)。 因此最坏时间复杂度为 O(n log n),题目说法正确。
【易错点】 归并排序不是 O(n^2),因为每层处理总量始终只有 n。
第 4 题(判断题)
5个相同的红球和4个相同的蓝球排成一排,要求每个蓝球的两侧都必须至少有一个红球,则一共有15种排列方案。
正确答案错误
解析详情
【答案】错误
【考点】限制条件下的排列计数
【解析】 “每个蓝球两侧都至少有一个红球”说明蓝球不能在两端,且任意两个蓝球不能相邻。4个蓝球只能被5个红球隔开,唯一满足条件的排列是 RBRBRBRBR。 所以方案数只有 1 种,不是 15 种。
【易错点】 相同颜色的球不可区分,很多看似不同的位置选择实际上是同一种排列。
第 5 题(判断题)
使用 math.h 或 cmath 头文件中的函数,表达式 log(8) 的结果类型为 double、值约为 3。
正确答案错误
解析详情
【答案】错误
【考点】对数函数
【解析】 `log(8)` 在 `math.h/cmath` 中默认表示自然对数,即 ln(8)≈2.079,而不是 3。返回类型是 double 这一点对,但数值判断错了。
【易错点】 只有 `log2(8)` 才等于 3,`log(8)` 不是以2为底。
第 6 题(判断题)
C++是一种面向对象编程语言,C则不是。继承是面向对象三大特性之一,因此,使用C语言无法实现继承。
正确答案错误
解析详情
【答案】错误
【考点】面向对象思想与语言能力
【解析】 C 语言没有类和继承这样的原生语法支持,但并不等于“无法实现继承思想”。通过结构体嵌套、函数指针等方式,仍可以手工模拟类似继承和多态的效果。
【易错点】 “没有语言级关键字支持”不等于“完全做不到类似设计”。
第 7 题(判断题)
n个顶点的无向完全图,有棵生成树。
正确答案正确
解析详情
【答案】正确
【考点】完全图生成树计数
【解析】 这是 Cayley 公式:n 个顶点的无向完全图 K_n 的生成树数量为 n^(n-2)。 因此题目说法正确。
【易错点】 这个公式只适用于完全图,不是任意 n 个顶点的图都能直接套用。
第 8 题(判断题)
已知三个 double 类型的变量 a、b 和 theta 分别表示一个三角形的两条边长及二者的夹角(弧度),则三角形的周长可以通过表达式和求解。
正确答案错误
解析详情
【答案】错误
【考点】余弦定理与三角形周长
【解析】 表达式 `sqrt(a*a + b*b - 2*a*b*cos(theta))` 根据余弦定理求出的是第三边长 c,不是周长。 三角形周长应为 `a + b + c`,所以题目说法错误。
【易错点】 先分清“边长公式”和“周长公式”,二者只差一步但含义不同。
第 9 题(判断题)
有V个顶点、E条边的图的深度优先搜索遍历时间复杂度为。
正确答案正确
解析详情
【答案】正确
【考点】深度优先搜索复杂度
【解析】 DFS 遍历时每个顶点最多被访问一次,每条边也只会被检查常数次,因此总时间复杂度是 O(V+E)。
【易错点】 遍历图时不能只看顶点数,边的扫描代价同样要计入。
第 10 题(判断题)
从32名学生中选出4人分别担任班长、副班长、学习委员和组织委员,老师要求班级综合成绩排名最后的4名学生不得参选班长或学习委员(仍可以参选副班长和组织委员),则共有种不同的选法。
正确答案正确
解析详情
【答案】正确
【考点】分类乘法计数
【解析】 班长有 28 种选法,副班长可从剩余 31 人中选,学习委员此时还剩 27 个符合条件的人可选,组织委员再从剩余 29 人中选。 总数为 28×31×27×29,正好等于 30×29×28×27=P(30,4),所以题目说法正确。
【易错点】 限制只作用于“班长”和“学习委员”,副班长、组织委员仍可从全部剩余学生中选。