GESP 客观题评测系统

试卷解析 · 理解每一步

普及组 CSP-J 2026 初赛模拟卷 5

CSPJ-2026-R1-Mock-5

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

一、单项选择题

(共 15 题,每题 2 分,共计 30 分;每题有且仅有一个正确选项)

第 1 题(单选题,2 分)

以下关于存储器的说法中,错误的是( )。

A.
RAM 中的信息在断电后会丢失
B.
CPU 可以直接从硬盘中读取指令并执行
C.
内存的访问速度通常比外存快
D.
ROM 是一种只读存储器

正确答案B

解析详情
答案 B存储体系与指令执行
思路与推导
  1. CPU 执行指令前,必须先把硬盘中的程序装入内存,不能直接从硬盘取指执行。RAM 断电丢失数据、内存通常快于外存、ROM 为只读存储器均是正确描述。

第 2 题(单选题,2 分)

对于变量 `a = 7, b = 4`,表达式 `(a ^ b) & ((~a) | b)` 的结果是( )。

A.
3
B.
4
C.
7
D.
0

正确答案D

解析详情
答案 D位运算
思路与推导
  1. a=7a=7 的低三位为 111,b=4b=4 为 100,按位异或后得到 3;对 a 按位取反得到 -8,再与 4 按位或得到 -4。最后 3 与 -4 按位与的结果为 0。

第 3 题(单选题,2 分)

一个 8 位有符号整数采用二进制补码表示,其可以表示的最小十进制数是( )。

A.
-127
B.
-128
C.
-255
D.
-256

正确答案B

解析详情
答案 B补码表示范围
思路与推导
  1. nn 位有符号补码的范围是 [−2n−1,2n−1−1][-2^{n-1},2^{n-1}-1]。取 n=8n=8,最小值为 −27=−128-2^7=-128。

第 4 题(单选题,2 分)

在 NOI Linux 终端中,要创建一个名为 `test` 的新目录,应该使用( )命令。

A.
`new test`
B.
`create test`
C.
`mkdir test`
D.
`md test`

正确答案C

解析详情
答案 CLinux 目录操作命令
思路与推导
  1. mkdir 用于创建目录,因此 mkdir test 会在当前路径下新建名为 test 的目录。

第 5 题(单选题,2 分)

xx 是正整数且在 `int` 范围内,则表达式 `(x & (x - 1)) == 0` 可以用来判断一个无符号整数 xx( )。

A.
是偶数
B.
是 2 的幂次
C.
是 0
D.
是奇数

正确答案B

解析详情
答案 B二进制位性质
思路与推导
  1. x−1x-1 会把 xx 最低的 1 变为 0,并把其后的 0 变为 1;与 xx 按位与后相当于清除最低的 1。正整数结果为 0 当且仅当原数只有一个 1,即 x=2kx=2^k。

第 6 题(单选题,2 分)

在平均情况下,( )算法的时间复杂度最低。

A.
冒泡排序
B.
插入排序
C.
快速排序
D.
选择排序

正确答案C

解析详情
答案 C排序算法复杂度
思路与推导
  1. 快速排序平均每层划分处理 nn 个元素,递归深度平均为 O(log⁡n)O(\log n),总时间为 O(nlog⁡n)O(n\log n)。冒泡、插入和选择排序的平均时间均为 O(n2)O(n^2)。

第 7 题(单选题,2 分)

以下代码的空间复杂度是( )。

int sum = 0;
for (int i = 0; i < n; i++) {
    int temp = i * 2;
    sum += temp;
}
A.
O(1)O(1)
B.
O(n)O(n)
C.
O(n2)O(n^2)
D.
O(log⁡n)O(\log n)

正确答案A

解析详情
答案 A辅助空间复杂度
思路与推导
  1. 循环只使用 sum、i、temp 等固定数量的标量变量,没有随 nn 增长的数组或递归栈,因此额外空间为 O(1)O(1)。

第 8 题(单选题,2 分)

一个项目团队有 12 名成员,任意两名成员之间都有直接合作关系。若用顶点表示成员、用边表示直接合作关系,则最准确描述该图结构的是( )。

A.
连通图,但不一定是完全图
B.
12 个顶点的完全图 K12K_{12}
C.
一棵有 12 个顶点的树
D.
一个有向无环图

正确答案B

解析详情
答案 B完全图
思路与推导
  1. 任意两名成员之间都有直接合作关系,意味着任意两个顶点之间都有一条边,因此该图恰好是 12 个顶点的完全图 K12K_{12}。

第 9 题(单选题,2 分)

一个栈的入栈序列为 1,2,3,4,5,6。出栈序列中,3 是第二个出栈的元素。出栈序列( )是不可能的。

A.
1,3,2,4,5,6
B.
2,3,4,6,1,5
C.
4,3,2,1,5,6
D.
2,3,4,1,5,6

正确答案B

解析详情
答案 B栈的出栈序列
思路与推导
  1. 序列 B 弹出 2、3、4 后,为先弹出 6 必须把 5、6 依次压栈;弹出 6 后栈顶仍是 5,不可能越过 5 先弹出 1。因此该序列不可能出现。

第 10 题(单选题,2 分)

5 个男生和 3 个女生站成一排,要求女生不相邻,且第一个和最后一个位置必须是男生,不同的排法有( )种。

A.
1440
B.
2160
C.
2880
D.
4320

正确答案C

解析详情
答案 C插空排列
思路与推导
  1. 先排列 5 个男生有 5!5! 种。两端必须是男生且女生不相邻,所以 3 个女生只能放入男生之间的 4 个空隙,选 3 个空隙并排列女生,共 (43)×5!×3!=2880\binom{4}{3}\times 5!\times 3!=2880 种。

第 11 题(单选题,2 分)

已知二叉树的中序遍历序列为 DBEAC,后序遍历序列为 DEBCA,则前序遍历序列为( )。

A.
ABCDE
B.
ABDEC
C.
ABEDC
D.
ABECD

正确答案B

解析详情
答案 B二叉树遍历还原
思路与推导
  1. 后序末尾 A 是根;中序 DBEAC 将左子树分为 DBE、右子树分为 C。左子树后序为 DEB,故其根为 B,左右孩子分别为 D、E,前序得到 ABDEC。

第 12 题(单选题,2 分)

用数组存储完全二叉树,按从上到下、从左到右的顺序编号(从 1 开始),则节点 ii 的左子节点是( )。

A.
2i2i
B.
2i+12i+1
C.
i/2i/2
D.
(i+1)/2(i+1)/2

正确答案A

解析详情
答案 A完全二叉树顺序存储
思路与推导
  1. 从 1 开始编号时,节点 ii 的两个孩子编号依次为 2i2i 和 2i+12i+1,因此左子节点是 2i2i。

第 13 题(单选题,2 分)

以下关于 CPU(中央处理器)的描述中,正确的是( )。

A.
CPU 主要由存储器和控制器组成
B.
CPU 的性能仅由主频决定
C.
多核 CPU 是指一个 CPU 中有多个运算器
D.
CPU 是计算机的“大脑”,负责所有的运算和控制

正确答案D

解析详情
答案 DCPU 的组成与作用
思路与推导
  1. CPU 承担指令解释、算术逻辑运算和整机控制,是计算机的核心处理部件。它主要由运算器、控制器和寄存器等组成,性能还受架构、缓存、核心数等多种因素影响。

第 14 题(单选题,2 分)

学校有 nn 门课程,部分课程有先修关系(必须先修 A 才能修 B)。现要判断课程安排是否合理,有没有循环依赖。这对应图论中的( )问题。

A.
最短路径
B.
拓扑排序
C.
最小生成树
D.
负环

正确答案B

解析详情
答案 B拓扑排序与有向环检测
思路与推导
  1. 把课程作为顶点、先修关系作为有向边,合理的修课顺序就是该图的拓扑序。若拓扑排序无法处理全部 nn 个顶点,则图中存在环,也就是循环依赖。

第 15 题(单选题,2 分)

某哈夫曼树有 8 个叶节点,该树总共有( )个节点。

A.
8
B.
15
C.
16
D.
17

正确答案B

解析详情
答案 B哈夫曼树节点数
思路与推导
  1. 哈夫曼树是每个内部节点都有两个孩子的满二叉树。叶节点数为 L=8L=8 时,内部节点数为 L−1=7L-1=7,总节点数为 8+7=158+7=15。

二、阅读程序(1)

1 | #include <iostream>
2 | using namespace std;
3 |
4 | int process(int n) {
5 |     if (n == 0) return 0;
6 |     return n % 2 + process(n / 2) * 10;
7 | }
8 |
9 | int main() {
10 |     int num;
11 |     cin >> num;
12 |     int result = process(num);
13 |     cout << result << endl;
14 |     return 0;
15 | }

第 16 题(判断题,2 分)

输入 10 时,输出为 1010。( )

正确答案正确

解析详情
答案 正确递归进制转换
思路与推导
  1. process(10) 依次递归到 5、2、1、0,再按返回顺序计算:1、10、101、1010,所以最终输出 1010。

第 17 题(判断题,2 分)

输入 1024 时,输出为 10000000000。( )

正确答案错误

解析详情
答案 错误整数溢出与递归返回
思路与推导
  1. 数学上 1024=2101024=2^{10} 会生成 10000000000,但该十进制整数大于 32 位 int 上限 2147483647。递归返回时发生有符号整数溢出,不能正常输出 10000000000。

第 18 题(判断题,2 分)

对于任意正整数 nn,`process(n)` 的输出总是一个由 0 和 1 组成的数。( )

正确答案错误

解析详情
答案 错误递归结果与数据范围
思路与推导
  1. 每层产生的余数确实只有 0 或 1,但函数把这些位拼成 int。输入较大时拼成的十进制整数会溢出,实际结果不再保证是只含 0、1 的有效数。

第 19 题(单选题,2 分)

若输入 2025,则函数 `process` 被递归调用( )次(包括第一次调用)。

A.
10
B.
11
C.
12
D.
13

正确答案C

解析详情
答案 C递归调用次数
思路与推导
  1. 2025 连续整除 2 得到 2025、1012、506、253、126、63、31、15、7、3、1、0,共 12 个参数值。包括终止条件 process(0) 在内,递归调用 12 次。

第 20 题(单选题,2 分)

函数 `process` 的时间复杂度是( )。

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

正确答案C

解析详情
答案 C递归时间复杂度
思路与推导
  1. 每次调用把 n 变为 ⌊n/2⌋\lfloor n/2\rfloor,到 0 需要约 ⌊log⁡2n⌋+1\lfloor\log_2 n\rfloor+1 层;每层只做常数次运算,所以时间复杂度为 O(log⁡n)O(\log n)。

第 21 题(单选题,3 分)

程序能正常处理的最大输入值为( )。

A.
1023
B.
1024
C.
1000000000
D.
231−12^{31}-1

正确答案A

解析详情
答案 A递归计算的数据范围
思路与推导
  1. process(1023) 生成 1111111111,小于 int 上限 2147483647;从 1024 起二进制表示有 11 位,拼成的十进制整数至少为 10000000000,超出 int。故能正常处理的最大输入值为 1023。

二、阅读程序(2)

1 | #include <iostream>
2 | #include <cmath>
3 | #define MAX 100
4 | using namespace std;
5 | int digits[MAX + 9];
6 | void solve(int a, int b, int precision) {
7 |     if (b == 0) {
8 |         cout << "Error: Division by zero!" << endl;
9 |         return;
10 |     }
11 |     if (precision > MAX) precision = MAX;
12 |     if (precision < 0) precision = 0;
13 |
14 |     bool negative = (a < 0 && b > 0) || (a > 0 && b < 0);
15 |     a = abs(a);
16 |     b = abs(b);
17 |     digits[0] = a / b;
18 |     int remainder = a % b;
19 |
20 |     for (int i = 1; i <= precision + 1; i++) {
21 |         remainder *= 10;
22 |         digits[i] = remainder / b;
23 |         remainder %= b;
24 |     }
25 |
26 |     if (digits[precision + 1] >= 5) {
27 |         digits[precision]++;
28 |         for (int i = precision; i >= 1; i--) {
29 |             if (digits[i] >= 10) {
30 |                 digits[i] -= 10;
31 |                 digits[i - 1]++;
32 |             } else {
33 |                 break;
34 |             }
35 |         }
36 |     }
37 |
38 |     if (negative) cout << "-";
39 |     cout << digits[0] << '.';
40 |     for (int i = 1; i <= precision; i++) {
41 |         cout << digits[i];
42 |     }
43 |     cout << endl;
44 | }
45 |
46 | int main() {
47 |     int a, b, prec;
48 |     cin >> a >> b >> prec;
49 |     solve(a, b, prec);
50 |     return 0;
51 | }
52 | // 所有输入数据的绝对值均小于 1000

第 22 题(判断题,2 分)

程序输出结果保留指定的小数位数,同时实现四舍五入,小数位的数量等于输入变量 `prec` 的值。( )

正确答案错误

解析详情
答案 错误输出精度限制与四舍五入
思路与推导
  1. 程序会先把 precision 限制到 [0,100][0,100]:大于 100 时只输出 100 位,小于 0 时按 0 位处理。因此输出小数位数不一定等于原始输入 prec,虽然有效范围内会利用下一位完成四舍五入。

第 23 题(判断题,2 分)

若输入 `2025 25 0`,程序会输出 81。( )

正确答案错误

解析详情
答案 错误零位小数的输出格式
思路与推导
  1. 2025/25=812025/25=81 且余数为 0;precision 为 0 时小数数字循环不执行,但第 39 行仍会输出小数点。因此实际输出是 81.,不是 81。

第 24 题(判断题,2 分)

若将程序中的 `solve(a, b, prec);` 替换成 `cout << fixed << setprecision(prec) << (1.0 * a / b) << endl;`,其他部分不变,则当 `prec` 的输入值在 [0,15][0,15] 区间时,输出结果是一样的。( )

正确答案错误

解析详情
答案 错误格式化输出差异
思路与推导
  1. 取 prec=0 即可反例:原 solve 会无条件输出 digits[0] 后的点号,而 fixed 与 setprecision(0) 只输出取整后的数,不带小数点。故即使 prec 限制在 [0,15][0,15],两种输出也不总相同。

第 25 题(单选题,3 分)

如果输入 `2026 26 4`,则输出的结果是( )。

A.
77.923
B.
77.9230
C.
77.9231
D.
77.9232

正确答案C

解析详情
答案 C小数展开与进位
思路与推导
  1. 2026/262026/26 的整数部分为 77、余数为 24,依次产生小数位 9、2、3、0,下一位为 7。因为第 5 位不小于 5,第 4 位由 0 进为 1,输出 77.9231。

第 26 题(单选题,3 分)

如果输入的数据为 `2026 0 -6`,下列说法中正确的是( )。

A.
程序会因为执行除以 0 的操作而出错,不能正常输出数据
B.
程序不会报错,但不会输出具体数值,而是输出自定义的出错提示语
C.
程序不会报错,可以正常输出结果,输出结果为 `2026.`
D.
程序不会报错,可以正常输出结果,输出结果为 `2026`

正确答案B

解析详情
答案 B除零保护与提前返回
思路与推导
  1. solve 首先判断 b==0,输出 Error: Division by zero! 后立即 return,因此不会执行 a/b 或 a%b,也不会输出具体数值。prec=-6 对这一分支没有影响。

二、阅读程序(3)

1 | #include <iostream>
2 | #include <vector>
3 | using namespace std;
4 |
5 | int bSearch(vector<int>& a, int target) {
6 |     int left = 0, right = a.size() - 1;
7 |
8 |     while (left <= right) {
9 |         int mid = left + (right - left) / 2;
10 |         if (a[mid] == target) {
11 |             return mid;
12 |         } else if (a[mid] > target) {
13 |             left = mid + 1;
14 |         } else {
15 |             right = mid - 1;
16 |         }
17 |     }
18 |     return -1;
19 | }
20 |
21 | int main() {
22 |     int n, x;
23 |     cin >> n >> x;
24 |
25 |     vector<int> a(n);
26 |     for (int i = 0; i < n; i++) cin >> a[i];
27 |     int ans = bSearch(a, x);
28 |     cout << (ans != -1 ? ans : -1) << endl;
29 |     return 0;
30 | }

第 27 题(判断题,2 分)

如果输入 `6 3 10 9 8 6 5 4`,程序会输出 -1。( )

正确答案正确

解析详情
答案 正确降序数组二分查找
思路与推导
  1. 初始 mid=2,a[2]=8>3,令 left=3;随后检查下标 4 的 5 和下标 5 的 4,left 最终变为 6。此时 left>right,函数返回 -1。

第 28 题(判断题,2 分)

该程序使用二分法,在单调不升数组中查找某个数在整个数组中排在第几个位置。( )

正确答案错误

解析详情
答案 错误二分查找返回值
思路与推导
  1. 程序确实在单调不升数组中二分查找,但找到后直接返回 mid,即从 0 开始的数组下标。它没有统计比目标大的元素数,也没有转换成通常从 1 开始的名次。

第 29 题(判断题,2 分)

要保证正常查找功能,输入必须从大到小排列,并且数值要连续。( )

正确答案错误

解析详情
答案 错误二分查找的单调性条件
思路与推导
  1. 分支方向要求数组单调不升,但相邻数值可以相等,也可以有任意大小的间隔。例如 10、7、3 仍满足该二分查找的前提,不需要数值连续。

第 30 题(单选题,3 分)

如果输入 `10 4 20 17 15 11 10 9 8 6 5 3`,程序会输出( )。

A.
11
B.
10
C.
8
D.
-1

正确答案D

解析详情
答案 D降序二分过程追踪
思路与推导
  1. 查找 4 时依次检查下标 4、7、8、9,对应值为 10、6、5、3。前三个值大于 4 使 left 右移,最后 3 小于 4 使 right 变为 8,区间为空后返回 -1。

第 31 题(单选题,3 分)

如果输入单调不升数组,被查找的数值出现过多次,则程序输出是( )。

A.
匹配的最小的下标
B.
匹配的最大的下标
C.
任意一个匹配的下标都有可能
D.
-1

正确答案C

解析详情
答案 C重复元素的二分查找
思路与推导
  1. 一旦 a[mid]==target,函数立即返回 mid,之后不再向左或向右收缩边界。因此返回哪个重复元素取决于二分过程中首先命中的 mid,不保证是最小或最大下标。

第 32 题(单选题,3 分)

如果输入 `4 4 4 4 4 4`,程序会输出( )。

A.
0
B.
1
C.
2
D.
3

正确答案B

解析详情
答案 B二分中点计算
思路与推导
  1. 输入表示 n=4、target=4,数组四项也全为 4。初始 left=0、right=3,第一次计算 mid=0+(3-0)/2=1,立即匹配并返回 1。

三、完善程序(1)不相邻元素最大和

给定一个整数数组和一个整数 kk,程序找出数组中 kk 个不相邻元素(即任意两个被选元素在数组中不相邻)的最大和。

1 | #include <iostream>
2 | #include <vector>
3 | #include <algorithm>
4 | using namespace std;
5 |
6 | int solve(vector<int>& nums, int k) {
7 |     int n = ①;
8 |     vector<vector<int>> dp(②);
9 |
10 |     for (int i = 1; i <= n; i++) {
11 |         for (int j = 1; j <= k; j++) {
12 |             if (j == 1) {
13 |                 dp[i][j] = max(③);
14 |             } else {
15 |                 dp[i][j] = max(dp[i - 1][j], ④);
16 |             }
17 |         }
18 |     }
19 |     return ⑤;
20 | }
21 |
22 | int main() {
23 |     int n, k;
24 |     cin >> n >> k;
25 |     vector<int> nums(n);
26 |     for (int i = 0; i < n; i++) cin >> nums[i];
27 |     cout << solve(nums, k) << endl;
28 |     return 0;
29 | }

第 33 题(单选题,3 分)

① 处应填( )。

A.
nums.size() - 1
B.
nums.size()
C.
nums.length() - 1
D.
nums.length()

正确答案B

解析详情
答案 Bvector 容器长度
思路与推导
  1. 后续循环按 i=1 到 n 处理 nums 的全部元素,所以 n 应等于 nums.size()。vector 没有 length() 成员,且减 1 会漏掉最后一个元素。

第 34 题(单选题,3 分)

② 处应填( )。

A.
n, vector<int>(k, 0)
B.
n, vector<int>(k + 1, 0)
C.
n + 1, vector<int>(k, 0)
D.
n + 1, vector<int>(k + 1, 0)

正确答案D

解析详情
答案 D动态规划数组边界
思路与推导
  1. dp[i][j] 表示在前 i 个元素中选择 j 个不相邻元素的最大和;状态需要覆盖 i=0…ni=0\ldots n 和 j=0…kj=0\ldots k。因此二维表应开为 n+1 行、每行 k+1 列并初始化为 0。

第 35 题(单选题,3 分)

③ 处应填( )。

A.
dp[i - 1][j], nums[i - 1]
B.
dp[i][j], nums[i - 1]
C.
dp[i - 1][j - 1] + nums[i - 1]
D.
dp[i][j] + nums[i - 1]

正确答案A

解析详情
答案 A动态规划状态转移
思路与推导
  1. 当 j=1 时,第 i 个元素有“不选”和“选”两种情况:不选沿用 dp[i-1][1],选它的和就是 nums[i-1],因此两者取最大值。若数组允许全负数且必须恰选 1 个,原框架还需把不可达状态初始化为负无穷。

第 36 题(单选题,3 分)

④ 处应填( )。

A.
dp[i - 1][j], nums[i - 1]
B.
dp[i][j], nums[i - 1]
C.
dp[i - 2][j - 1] + nums[i - 1]
D.
dp[i][j] + nums[i - 1]

正确答案C

解析详情
答案 C不相邻选择的动态规划
思路与推导
  1. 在可达状态中,若选择 nums[i-1],其余 j-1 个只能来自前 i-2 个元素,得到 dp[i-2][j-1]+nums[i-1];再与 dp[i-1][j] 取最大值。原框架还应避免在 i=1、j>1 时访问 dp[-1][j-1],但这不改变空④的转移项。

第 37 题(单选题,3 分)

⑤ 处应填( )。

A.
dp[n - 1][k - 1]
B.
dp[n][k - 1]
C.
dp[n - 1][k]
D.
dp[n][k]

正确答案D

解析详情
答案 D动态规划目标状态
思路与推导
  1. 程序处理完全部 n 个元素后,需要得到“从前 n 个元素中选择 k 个”的最大和,对应目标状态 dp[n][k]。

三、完善程序(2)区间覆盖

给定一条长度为 LL 的线段(LL 为整数),以及 nn 个整数区间,每个区间有整数起始位置和结束位置。程序的目标是选择最少数量的区间,使得这些区间完全连续覆盖整个线段 [0,L][0,L]。如果无法完全覆盖,则输出 -1。

1 | #include <iostream>
2 | #include <algorithm>
3 | using namespace std;
4 | const int N = 100005;
5 |
6 | struct Interval { int s, e; } ivl[N];
7 | bool cmp(Interval a, Interval b) {
8 |     return a.s < b.s || (①);
9 | }
10 |
11 | int main() {
12 |     int L, n;
13 |     cin >> L >> n;
14 |
15 |     for (int i = 0; i < n; i++) {
16 |         cin >> ivl[i].s >> ivl[i].e;
17 |     }
18 |     ②
19 |
20 |     int curr = 0;
21 |     int cnt = 0;
22 |     int i = 0;
23 |
24 |     while (curr < L) {
25 |         int mx_reach = curr;
26 |         while (③) {
27 |             if (ivl[i].e > mx_reach) {
28 |                 mx_reach = ivl[i].e;
29 |             }
30 |             i++;
31 |         }
32 |
33 |         if (④) {
34 |             cout << -1 << endl;
35 |             return 0;
36 |         }
37 |         cnt++;
38 |         ⑤
39 |     }
40 |
41 |     cout << cnt << endl;
42 |     return 0;
43 | }

第 38 题(单选题,3 分)

① 处应填( )。

A.
a.s == b.s && a.e < b.e
B.
a.s == b.s && a.e <= b.e
C.
a.s == b.s && a.e != b.e
D.
a.s == b.s && a.e >= b.e

正确答案A

解析详情
答案 A排序比较函数
思路与推导
  1. cmp 先按起点 a.s 升序排列;当起点相同时,应再用 a.e<b.e 按终点升序排列,所以补充条件为 a.s==b.s 且 a.e<b.e。严格小于也满足 sort 所需的严格弱序。

第 39 题(单选题,3 分)

② 处应填( )。

A.
sort(ivl, ivl + n);
B.
sort(ivl, ivl + n, cmp);
C.
sort(ivl + 1, ivl + 1 + n);
D.
sort(ivl + 1, ivl + 1 + n, cmp);

正确答案B

解析详情
答案 Bsort 的区间与比较器
思路与推导
  1. ivl 中的 n 个区间存放在下标 0…n−10\ldots n-1,sort 使用左闭右开区间,因此范围应为 [ivl,ivl+n)。同时必须传入 cmp 才能按结构体的起点、终点排序。

第 40 题(单选题,3 分)

③ 处应填( )。

A.
i < n && ivl[i].s > curr
B.
i < n && ivl[i].s >= curr
C.
i < n && ivl[i].s <= curr
D.
i < n && ivl[i].s < curr

正确答案C

解析详情
答案 C区间覆盖贪心
思路与推导
  1. 当前已经连续覆盖到 curr,下一步必须考察所有起点 ivl[i].s<=curr 的区间,并从中选择终点最大的一个。起点大于 curr 的区间会在 curr 后留下空隙,不能接续覆盖。

第 41 题(单选题,3 分)

④ 处应填( )。

A.
i < n
B.
i > n
C.
mx_reach < curr
D.
mx_reach == curr

正确答案D

解析详情
答案 D区间覆盖不可达判定
思路与推导
  1. mx_reach 初始等于 curr;扫描所有起点不大于 curr 的区间后,若 mx_reach 仍等于 curr,说明没有区间能把覆盖右端向前推进,区间链在此处中断,只能输出 -1。

第 42 题(单选题,3 分)

⑤ 处应填( )。

A.
curr = mx_reach;
B.
curr += mx_reach;
C.
curr = intervals[i].e;
D.
curr += intervals[i].e - intervals[i].s + 1;

正确答案A

解析详情
答案 A最少区间覆盖的贪心推进
思路与推导
  1. 内层循环已在所有可衔接区间中求出最远终点 mx_reach;选定这一个区间后,连续覆盖的右端应直接更新为 curr=mx_reach,并把 cnt 增加 1。