GESP 客观题评测系统

试卷解析 · 理解每一步

2025-06-Level-8

2025-06-Level-8

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

单选题

第 1 题(单选题,2 分)

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

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

正确答案A

解析详情
答案 A座位排列
思路与推导
  1. 六个座位的行列位置均不同,六名同学可以任意一一对应地坐入。

  2. 试卷由座位所在列决定,并未事先限定哪些同学只能做 A 卷或 B 卷,因此方案数仍为 6!=7206!=720,选 A。

第 2 题(单选题,2 分)

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

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

正确答案B

解析详情
答案 B男女交替排列
思路与推导
  1. 男生、女生各三人,且同类不能相邻,所以性别顺序只能为男女男女男女,或女男女男女男。

  2. 每种性别顺序内,男生有 3! 种排列,女生也有 3! 种,共 2×3!×3!=722×3!×3!=72,选 B。

第 3 题(单选题,2 分)

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

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

正确答案D

解析详情
答案 D声明与定义
思路与推导
  1. class MyClass; 只是类的前向声明,说明这个类型名存在,没有给出成员等完整类定义,因此 D 错误。

  2. C++ 的对象概念不限于类实例:具有存储的整数、字符串实例和函数指针变量,都可以是对象,所以前三项并不因类型不同而错误。

第 4 题(单选题,2 分)

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

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

正确答案D

解析详情
答案 D生成树的连通条件
思路与推导
  1. n 个顶点、n−1 条边并不能独自保证连通。比如 4 个顶点中,3 个连成三角形,另一个孤立,共有 3 条边,但没有生成树。

  2. 因此 D 缺少连通条件。若这样的图连通,则本身就是树;若不连通,则生成树不存在,故也不可能有多棵生成树。

第 5 题(单选题,2 分)

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

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

正确答案C

解析详情
答案 C独立事件概率
思路与推导
  1. 按两次生育性别独立、男女各半的假设,两孩性别顺序为男男、男女、女男、女女,四种等概率。

  2. 儿女双全包含男女和女男两种,概率为 2/4=1/22/4=1/2,选 C。

第 6 题(单选题,2 分)

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

A.
4∗b−a∗a<04 * b - a * a < 0
B.
4∗b<=a∗a4 * b <= a * a
C.
a∗a−4∗ba * a - 4 * b
D.
b∗4−a∗ab * 4 - a * a

正确答案B

解析详情
答案 B一元二次方程判别式
思路与推导
  1. 方程首项系数为 1,判别式为 Δ=a2−4b\Delta=a^2-4b。有实根要求 Δ≥0,包括 Δ=0 的重根。

  2. 等价变形得到 4b≤a24b≤a^2,对应 B。A 的严格不等式漏掉重根,C、D 则没有完成真假比较。

第 7 题(单选题,2 分)

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

A.
O(log⁡n)O(\log n)
B.
O(nlog⁡n)O(n \log n)
C.
O(n)O(n)
D.
O(2n)O(2^n)

正确答案C

解析详情
答案 C二叉树 BFS
思路与推导
  1. 完整 BFS 中,每个结点入队、出队各一次;检查左右孩子也只需常数时间。

  2. n 个结点的总工作量为 O(n)O(n),选 C,不因树平衡与否改变。

第 8 题(单选题,2 分)

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

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

正确答案B

解析详情
答案 B动态规划转移代价
思路与推导
  1. 动态规划总耗时通常是各状态转移耗时之和,而非仅数状态。

  2. 例如最长上升子序列的朴素 DP 只有 n 个状态,但第 i 个状态要枚举前面 i 个位置,总时间为 O(n2)O(n^2)。因此 B 错误。

第 9 题(单选题,2 分)

下面的 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(nlog⁡n)O(n \log n)
B.
O(n)O(n)
C.
O(log⁡n)O(\log n)
D.
O(n2)O(n^{2})

正确答案A

解析详情
答案 A数字枚举复杂度
思路与推导
  1. sum_digit 从 1 到 n 逐个调用 count_digit。整数 i 的十进制位数为 O(log⁡i)O(\log i),转换为字符串和逐位扫描均为此数量级。

  2. 总耗时为 ∑i=1nO(log⁡i)=O(nlog⁡n)\sum_{i=1}^n O(\log i)=O(n\log n),选 A。

  3. 注意代码累加的是数字 d 的出现次数,不是含 d 的整数个数:例如 11 对 '1' 贡献 2。

第 10 题(单选题,2 分)

下面程序的输出为()。

#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动态规划计数与程序输出
思路与推导
  1. 数组 `ch[x][y][z]` 表示从 (0,0,0) 走到 (x,y,z) 的路径数,每次只能沿三个坐标轴正方向前进,所以状态转移是三个前驱之和。

  2. 到达 (1,2,3) 一共要走 1+2+3=6 步,其中三类步分别出现 1、2、3 次,路径数为 6!/(1!2!3!)=60,因此输出 60。

第 11 题(单选题,2 分)

下面 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(nlog⁡n)O(n \log n)
D.
O(n2log⁡n)O(n^{2} \log n)

正确答案C

解析详情
答案 C循环规模估计与欧几里得算法
思路与推导
  1. 按题目意图分析,外层枚举 (u,v) 的总次数与 n 同阶;而每次判断 `gcd(u,v)==1` 用欧几里得算法,复杂度是 O(log n)。

  2. 因此整体时间复杂度为 O(n log n),对应 C。

第 12 题(单选题,2 分)

下面 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快速排序划分过程
思路与推导
  1. 按快速排序的标准划分思路,循环结束后 j 应停在最后一个“小于等于枢轴”的位置,因此应把枢轴与 a[j] 交换,让它落到最终位置。

  2. 随后返回的也应是这个最终位置 j,递归才能正确处理左右两段,所以选 D。

第 13 题(单选题,2 分)

下面 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 转移
思路与推导
  1. 设 `dp[i]` 表示以 `nums[i]` 结尾的最长上升子序列长度。若 `nums[j] < nums[i]`,就可以把 `nums[i]` 接在以 j 结尾的序列后面,因此转移为 `dp[i] = max(dp[i], dp[j] + 1)`。

  2. 这正是选项 D。

第 14 题(单选题,2 分)

下面 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(log⁡n)O(\log n)
B.
O(n)O(n)
C.
O(nlog⁡n)O(n \log n)
D.
O(n2)O(n^{2})

正确答案C

解析详情
答案 CLIS 的二分优化
思路与推导
  1. 外层循环处理每个元素一次,共 n 次;每次都在 `tail` 数组中用二分查找插入或替换位置,代价是 O(log n)。

  2. 所以总时间复杂度是 O(n log n),选 C。

第 15 题(单选题,2 分)

下面的程序使用邻接矩阵表达的带权无向图,则从顶点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带权最短路
思路与推导
  1. 从 0 直达 3 的权重为 10。若走 0→1→3,长度为 5+7=12;走 0→2→3 为 8+3=11。

  2. 利用边 1—2,可走 0→1→2→3,长度为 5+1+3=95+1+3=9,比前面均短,因此选 A。所有边为正,绕圈不会更优。

判断题

第 1 题(判断题,2 分)

C++语言中,表达式 9 | 12 的结果类型为 int、值为 13。

正确答案正确

解析详情
答案 正确按位或
思路与推导
  1. 9 的二进制为 1001,12 为 1100。对应位只要有一个为 1,按位或结果就为 1。

  2. 1001 与 1100 按位或得到 1101,即十进制 13;两个 int 操作数的结果也是 int,故正确。

第 2 题(判断题,2 分)

C++语言中,访问数据发生下标越界时,总是会产生运行时错误,从而使程序异常退出。

正确答案错误

解析详情
答案 错误越界与未定义行为
思路与推导
  1. 内置数组越界访问属于未定义行为,语言不保证自动检查边界。

  2. 程序可能崩溃,也可能读到无关数据、破坏其他内存,甚至暂时看似正常,所以“总会异常退出”错误。

第 3 题(判断题,2 分)

对n个元素的数组进行归并排序,最差情况的时间复杂度为O(nlog⁡n)O(n\log n)。

正确答案正确

解析详情
答案 正确归并排序最坏复杂度
思路与推导
  1. 归并排序每次将区间分为两半,递归深度为 O(log⁡n)O(\log n)。同一层合并的所有区间合计包含 n 个元素。

  2. 无论初始数据怎样,逐层处理量均为 O(n)O(n),所以最坏时间复杂度为 O(nlog⁡n)O(n\log n)。

第 4 题(判断题,2 分)

5个相同的红球和4个相同的蓝球排成一排,要求每个蓝球的两侧都必须至少有一个红球,则一共有15种排列方案。

正确答案错误

解析详情
答案 错误受限插空法
思路与推导
  1. “每个蓝球两侧都有红球”要求蓝球不能在两端,也不能互相相邻。

  2. 先排 5 个相同红球,只能使用中间的 4 个空隙。4 个蓝球必须一隙一个,得到唯一序列“红蓝红蓝红蓝红蓝红”。

  3. 因此只有 1 种,不是 15 种。

第 5 题(判断题,2 分)

使用 math.h 或 cmath 头文件中的函数,表达式 log(8) 的结果类型为 double、值约为 3。

正确答案错误

解析详情
答案 错误对数函数
思路与推导
  1. log(8) 返回浮点结果,但表示自然对数 ln⁡8≈2.0794\ln8≈2.0794,不是 3。

  2. log⁡28=3\log_2 8=3,应调用 log2(8),或用 log(8)/log(2),所以题目错误。

第 6 题(判断题,2 分)

C++是一种面向对象编程语言,C则不是。继承是面向对象三大特性之一,因此,使用C语言无法实现继承。

正确答案错误

解析详情
答案 错误继承机制的模拟
思路与推导
  1. C 没有 class 继承语法,但可在结构体中嵌入公共数据结构,并通过函数、指针和约定实现复用或多态等类似机制。

  2. 因此“不能直接写 C++ 继承语法”成立,“无法实现继承相关机制”则过强,题目判断错误。

第 7 题(判断题,2 分)

n个顶点的无向完全图,有nn−2n^{n-2}棵生成树。

正确答案正确

解析详情
答案 正确Cayley 公式
思路与推导
  1. 对具有 n 个不同标号顶点的完全图,生成树数量由 Cayley 公式给出,为 nn−2n^{n-2}(通常讨论 n≥2)。

  2. 可用 Prüfer 编码理解:每棵标号树唯一对应一个长度为 n−2 的编号序列,每位有 n 种选择,共 nn−2n^{n-2} 种。

第 8 题(判断题,2 分)

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

正确答案错误

解析详情
答案 错误三角形周长
思路与推导
  1. 已知两边 a、b 和夹角 θ,应先用余弦定理求第三边 c=a2+b2−2abcos⁡θc=\sqrt{a^2+b^2-2ab\cos\theta},再计算 a+b+c。

  2. 题中出现的 sqrt(a*b+c*d) 既含未给定的 c、d,也不符合余弦定理,因此错误。

第 9 题(判断题,2 分)

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

正确答案正确

解析详情
答案 正确DFS 复杂度
思路与推导
  1. 以邻接表存储并用访问标记避免重复进入时,每个顶点访问一次,每条邻接项扫描一次。

  2. 顶点操作为 O(V),边操作为 O(E),所以完整遍历为 O(V+E)O(V+E),判断正确。

第 10 题(判断题,2 分)

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

正确答案正确

解析详情
答案 正确限制职务排列
思路与推导
  1. 先安排受限制的班长、学习委员:两人都必须从符合条件的 28 人中选,依次有 28、27 种。

  2. 这两人选定后,副班长、组织委员可从其余全部同学中选,依次有 30、29 种。

  3. 总数为 28×27×30×29=30×29×28×27=P(30,4)28×27×30×29=30×29×28×27=P(30,4),所以正确。