GESP 客观题评测系统

2025-06-Level-8

2025-06-Level-8

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

单选题(每题 2 分)

1 题(单选题

一间的机房要安排6名同学进行上机考试,座位共2行3列。考虑到在座位上很容易看到同一行的左右两侧的屏幕,安排中间一列的同学做A卷,左右两列的同学做B卷。请问共有多少种排座位的方案?()。

A.
720
B.
90
C.
48
D.
15

正确答案A

解析详情

【答案】A

【考点】排列计数

【解析】 6个座位中有2个固定是A卷座位、4个固定是B卷座位,但题目并没有限制哪位同学必须做哪种卷,所以本质上只是把6名不同同学安排到6个不同位置。 方案数为 6!=720,因此选 A。

【易错点】 不要把“A卷座位有2个、B卷座位有4个”误当成还要再额外分类选择学生。

2 题(单选题

又到了毕业季,学长学姐们都在开心地拍毕业照。现在有3位学长、3位学姐希望排成一排拍照,要求男生不相邻、女生不相邻。请问共有多少种拍照方案?()。

A.
720
B.
72
C.
36
D.
2

正确答案B

解析详情

【答案】B

【考点】交错排列

【解析】 男生不相邻且女生不相邻,6个人只能按“男女男女男女”或“女男女男女男”两种性别顺序排。 每种顺序下,3位学长有 3! 种排法,3位学姐也有 3! 种排法,所以总数是 2×3!×3!=72。

【易错点】 先确定性别交错的整体骨架,再分别排列男生和女生,别直接把6人全排列。

3 题(单选题

下列关于C++类和对象的说法,错误的是( )。

A.
通过语句 const int x = 5;定义了一个对象 x。
B.
通过语句 std::string t = "12345"; 定义了一个对象 t。
C.
通过语句 void (*fp)() = NULL;定义了一个对象 fp。
D.
通过语句 class MyClass;定义了一个类 MyClass。

正确答案D

解析详情

【答案】D

【考点】C++ 类声明与对象

【解析】 A、B、C 中都定义了一个对象:常量对象 x、string 对象 t、函数指针对象 fp。 而 `class MyClass;` 只是对类名做前向声明,并没有给出类体,所以不能算“定义了一个类”,错误项是 D。

【易错点】 类的声明和类的定义不同,只有带类体的 `class MyClass { ... };` 才是完整定义。

4 题(单选题

关于生成树的说法,错误的是()。

A.
一个无向连通图,一定有生成树。
B.
n个顶点的无向图,其生成树要么不存在,要么一定包含n-1条边。
C.
n个顶点、n-1条边的无向图,不可能有多颗生成树。
D.
n个顶点、n-1条边的无向图,它本身就是自己的生成树。

正确答案D

解析详情

【答案】D

【考点】生成树性质

【解析】 A、B 都是生成树的基本性质:连通无向图一定有生成树,生成树一定含 n-1 条边。C 也对,因为一个 n 个点 n-1 条边的无向图若存在生成树,这棵生成树就只能用完全部边,因此不可能有多颗不同生成树。 D 错在遗漏“连通”条件。n个顶点、n-1条边的无向图若不连通,就不是树,更不可能是自己的生成树。

【易错点】 “边数等于 n-1”只是树的必要条件之一,连通性同样必不可少。

5 题(单选题

一对夫妻生男生女的概率相同。这对夫妻希望儿女双全。请问这对夫妻生下两个孩子时,实现儿女双全的概率是多少?()。

A.
23\frac{2}{3}
B.
13\frac{1}{3}
C.
12\frac{1}{2}
D.
14\frac{1}{4}

正确答案C

解析详情

【答案】C

【考点】古典概型

【解析】 两个孩子的性别等可能结果有 4 种:男男、男女、女男、女女。儿女双全对应“男女”和“女男”两种。 所以概率为 2/4=1/2,对应 C。

【易错点】 “男女”和“女男”是两个不同结果,不能只算成1种。

6 题(单选题

已定义变量 double a, b;,下列哪个表达式可以用来判断一元二次方程x2+ax+b=0x^2 + ax + b = 0是否有实根?()。

A.
4baa<04 * b - a * a < 0
B.
4b<=aa4 * b <= a * a
C.
aa4ba * a - 4 * b
D.
b4aab * 4 - a * a

正确答案B

解析详情

【答案】B

【考点】一元二次方程判别式

【解析】 方程 x^2+ax+b=0 有实根,当且仅当判别式 Δ=a^2-4b≥0。 把它移项可写成 4*b<=a*a,所以应选 B。A 只覆盖了两实根情形,漏掉重根;C、D 只是数值表达式,不是判断条件。

【易错点】 判断“有实根”要用 ≥0,不是严格大于0。

7 题(单选题

n 个结点的二叉树,执行广度优先搜索的平均时间复杂度是()。

A.
O(logn)O(\log n)
B.
O(nlogn)O(n \log n)
C.
O(n)O(n)
D.
O(2n)O(2^n)

正确答案C

解析详情

【答案】C

【考点】广度优先搜索复杂度

【解析】 在二叉树上做 BFS,每个结点最多入队、出队各一次,并访问其左右孩子常数次。 因此总工作量与结点数 n 成正比,时间复杂度是 O(n),选 C。

【易错点】 树高是 O(log n) 并不代表遍历整棵树也是 O(log n)。

8 题(单选题

以下关于动态规划的说法中,错误的是()。

A.
动态规划方法通常能够列出递推公式。
B.
动态规划方法的时间复杂度通常为状态的个数。
C.
动态规划方法有递推和递归两种实现形式。
D.
对很多问题,递推实现和递归实现动态规划方法的时间复杂度相当。

正确答案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.
O(nlogn)O(n \log n)
B.
O(n)O(n)
C.
O(logn)O(\log n)
D.
O(n2)O(n^{2})

正确答案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.
60
B.
20
C.
15
D.
10

正确答案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;
    }
}
A.
O(n)O(n)
B.
O(n2)O(n^{2})
C.
O(nlogn)O(n \log n)
D.
O(n2logn)O(n^{2} \log n)

正确答案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);
    }
}
A.
1 | swap(a[1], a[i]) 2 | i
B.
1 | swap(a[1], a[j]) 2 | i
C.
1 | swap(a[1], a[i]) 2 | j
D.
1 | swap(a[1], a[j]) 2 | j

正确答案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;
}
A.
1 | dp[j] = max(dp[j] + 1, dp[i])
B.
1 | dp[j] = max(dp[j], dp[i] + 1)
C.
1 | dp[i] = max(dp[i] + 1, dp[j])
D.
1 | dp[i] = max(dp[i], dp[j] + 1)

正确答案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;
        }
    }
}
A.
O(logn)O(\log n)
B.
O(n)O(n)
C.
O(nlogn)O(n \log n)
D.
O(n2)O(n^{2})

正确答案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.
9
B.
10
C.
11
D.
12

正确答案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个元素的数组进行归并排序,最差情况的时间复杂度为O(nlogn)O(n\log 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个顶点的无向完全图,有nn2n^{n-2}棵生成树。

正确答案正确

解析详情

【答案】正确

【考点】完全图生成树计数

【解析】 这是 Cayley 公式:n 个顶点的无向完全图 K_n 的生成树数量为 n^(n-2)。 因此题目说法正确。

【易错点】 这个公式只适用于完全图,不是任意 n 个顶点的图都能直接套用。

8 题(判断题

已知三个 double 类型的变量 a、b 和 theta 分别表示一个三角形的两条边长及二者的夹角(弧度),则三角形的周长可以通过表达式ab+cd\sqrt{a*b+c*d}cos(θ)\cos(\theta)求解。

正确答案错误

解析详情

【答案】错误

【考点】余弦定理与三角形周长

【解析】 表达式 `sqrt(a*a + b*b - 2*a*b*cos(theta))` 根据余弦定理求出的是第三边长 c,不是周长。 三角形周长应为 `a + b + c`,所以题目说法错误。

【易错点】 先分清“边长公式”和“周长公式”,二者只差一步但含义不同。

9 题(判断题

有V个顶点、E条边的图的深度优先搜索遍历时间复杂度为O(V+E)O(V+E)

正确答案正确

解析详情

【答案】正确

【考点】深度优先搜索复杂度

【解析】 DFS 遍历时每个顶点最多被访问一次,每条边也只会被检查常数次,因此总时间复杂度是 O(V+E)。

【易错点】 遍历图时不能只看顶点数,边的扫描代价同样要计入。

10 题(判断题

从32名学生中选出4人分别担任班长、副班长、学习委员和组织委员,老师要求班级综合成绩排名最后的4名学生不得参选班长或学习委员(仍可以参选副班长和组织委员),则共有P(30,4)P(30,4)种不同的选法。

正确答案正确

解析详情

【答案】正确

【考点】分类乘法计数

【解析】 班长有 28 种选法,副班长可从剩余 31 人中选,学习委员此时还剩 27 个符合条件的人可选,组织委员再从剩余 29 人中选。 总数为 28×31×27×29,正好等于 30×29×28×27=P(30,4),所以题目说法正确。

【易错点】 限制只作用于“班长”和“学习委员”,副班长、组织委员仍可从全部剩余学生中选。