一、单项选择题
(共 15 题,每题 2 分,共计 30 分;每题有且仅有一个正确选项)
试卷解析 · 理解每一步
CSPJ-2026-R1-Mock-4
试卷解析总览,可直接查看每题答案与解析。
(共 15 题,每题 2 分,共计 30 分;每题有且仅有一个正确选项)
在 NOI Linux 的终端中,要列出当前目录下所有文件和文件夹的详细信息(包括权限、大小、修改时间等),应该使用命令( )。
正确答案B
`ls -l` 使用长格式列出名称、权限、链接数、所有者、大小和修改时间等详细信息。
执行下面代码后,输出结果为( )。
int a = 6, b = 3;
cout << ((a & b) | (a ^ b));正确答案C
`6&3=2`,`6^3=5`,再计算 `2|5=7`,因此输出 7。
在 C++ 中,表达式 `!(5 > 3) && (4 <= 4) || (2 != 2)` 的结果是( )。
正确答案B
`5 > 3` 为真,取反后为假;假与任何值进行 `&&` 仍为假,`2 != 2` 也为假,所以整个表达式为 `false`。
关于单向链表,以下描述中正确的是( )。
正确答案D
单向链表的每个节点保存数据以及指向下一个节点的指针,节点不要求连续存储。
对于有 个节点的二叉树,其最小高度是( )。
正确答案B
高度按边数计算时,高度为 的二叉树最多有 个节点;反解得最小高度为 。
将十进制小数 100.25 转换为二进制数,结果是( )。
正确答案C
整数部分 ,二进制为 `1100100`;小数 ,二进制为 `.01`,合并得 `1100100.01`。
一个队列从空开始依次执行 `push(2)`、`push(5)`、`pop()`、`push(8)`。此时队首元素是( )。
正确答案C
队列先进先出,弹出的是最早进入的 2,之后队首为 5;再压入 8 不改变队首。
突然断电后,数据不会丢失的存储设备是( )。
正确答案C
固态硬盘使用非易失性闪存,断电后仍能保存数据;内存、缓存和寄存器均为易失性存储。
使用深度优先搜索(DFS)遍历一个 行 列的矩阵。从左上角开始搜索,每次只能向右或向下移动一个位置。在搜索过程中,需要使用一个栈来维护当前搜索路径上的已访问位置。为了确保能够完成整个矩阵的遍历,栈的大小至少为( )。(注:本题不考虑栈空间的大小限制。)
正确答案C
只向右或向下移动时,从左上角到右下角的最长路径包含 个位置,因此路径栈至少要能容纳这么多元素。
以下代码的时间复杂度是( )。
int n, i = 1;
cin >> n;
while (i < n) {
i = i * 3;
}正确答案C
变量 `i` 每轮乘 3,执行约 次;换底只带来常数因子,所以复杂度为 。
某城市有 8 个交通枢纽,如果要建设一个完全图式的道路网络,使得任意两个枢纽之间都有直达道路,需要建设( )条道路。
正确答案A
8 个顶点的无向完全图边数为 inom{8}{2}=8 imes7/2=28。
从 5 个不同的红球和 3 个不同的蓝球中,至少取 1 个球,最多取 4 个球,且红球和蓝球都必须至少取一个,不同的取法有( )种。
正确答案B
取 2、3、4 个球且两色非空的方案数分别为 15、45、65,总数为 。
一棵二叉搜索树中的关键字互不相同。能够按关键字严格递增顺序访问所有结点的遍历方式是( )。
正确答案B
二叉搜索树满足左子树关键字小于根、右子树关键字大于根,中序遍历按左、根、右访问,因此得到严格递增序列。
一个时间复杂度为 的算法,当 从 100 增大到 200 时,运行时间大约变为原来的( )倍。
正确答案C
当输入规模变为 2 倍时,立方复杂度的运行量变为 倍。
已知 `bool a=true, b=false, c=true`,表达式 `(!a || b) && c` 的值为( )。
正确答案B
`!a` 为假,`!a || b` 仍为假;假与 `c` 进行 `&&` 的结果为假,所以选择 `false`。
1 | #include <iostream>
2 | using namespace std;
3 | int solve(int x, int y) {
4 | if (y == 0) return x;
5 | if (x < y) swap(x, y);
6 | return solve(y, x - y);
7 | }
8 | int main() {
9 | int a, b;
10 | cin >> a >> b;
11 | int k = solve(a, b);
12 | cout << a / k << "/" << b / k << endl;
13 | return 0;
14 | }
15 | // 输入的 a 和 b 是不大于 10000 的正整数函数 `solve(int x, int y)` 计算 和 的最大公约数。( )
正确答案正确
函数通过反复交换并相减,把问题化为更小的一对正整数;当第二个参数为 0 时,第一个参数就是最大公约数。
把第 5 行代码去掉,程序会正常输出,但结果数值可能不对。( )
正确答案错误
删除交换后,若 `x < y`,下一次会传入负数 `x-y`,递归不能按预期收敛,最终可能栈溢出而无法正常输出。
如果输入的值为 160 和 115,则程序的输出结果为 `23/32`。( )
正确答案错误
,程序输出 `160/5` 与 `115/5`,即 `32/23`,不是 `23/32`。
如果输入 1817 和 299,则输出为( )。
正确答案D
,约分得到 、,所以输出 `79/13`。
如果输入 为 中随机生成的数,则程序的平均时间复杂度为( )。
正确答案B
对固定较大参数,辗转相减的平均步数与调和级数同阶;再对随机输入平均后仍为 。
1 | #include <iostream>
2 | using namespace std;
3 | int main() {
4 | int n, sum = 0;
5 | cin >> n;
6 | int arr[100];
7 | for (int i = 0; i < n; i++) {
8 | cin >> arr[i];
9 | }
10 | for (int i = 0; i < n; i++) {
11 | int cnt = 0;
12 | for (int j = 0; j < n; j++) {
13 | if (arr[j] > arr[i]) {
14 | cnt++;
15 | }
16 | }
17 | sum += (cnt == 1) * arr[i];
18 | }
19 | cout << sum << endl;
20 | return 0;
21 | }
22 | // 输入的所有数为绝对值均不大于 1000 的整数若输入数组为 `[5, 3, 8, 2]`,则程序输出为 5。( )
正确答案正确
数组中只有 5 恰好有一个比它大的元素 8,因此累加值为 5。
数组中可能存在多个元素满足条件,程序会将它们全部累加。( )
正确答案正确
循环逐个检查数组位置;若多个元素各自满足 `cnt == 1`,语句会把它们分别加入 `sum`。
如果程序输出为 0,则数组中的所有元素一定都相等。( )
正确答案错误
输出 0 还可能因为严格次大值本身为 0,或最大值重复导致没有元素满足 `cnt == 1`,并不能推出所有元素相等。
若输入数组为 `[9, 8, 7, 6, 5, 4, 3, 2, 1, 0, -1, -2]`,则输出为( )。
正确答案C
给定数组严格递减且元素互异,8 恰好只有一个更大的元素 9,因此程序输出 8。
该程序计算的是数组中( )。
正确答案C
对每个 `arr[i]`,内层循环统计严格大于它的元素数;程序累加所有统计值恰好为 1 的元素,所以选 C。
1 | #include <iostream>
2 | #include <vector>
3 | #include <algorithm>
4 | using namespace std;
5 |
6 | int n, k, ans = 0;
7 | vector<int> nums;
8 | vector<bool> used;
9 |
10 | void dfs(int pos, int sum, int count) {
11 | if (count == k) {
12 | if (sum % 2 == 0) {
13 | ans++;
14 | }
15 | return;
16 | }
17 | if (pos >= n) return;
18 |
19 | if (!used[pos]) {
20 | used[pos] = true;
21 | dfs(pos + 1, sum + nums[pos], count + 1);
22 | used[pos] = false;
23 | }
24 |
25 | dfs(pos + 1, sum, count);
26 | }
27 |
28 | int main() {
29 | cin >> n >> k;
30 | nums.resize(n);
31 | used.resize(n, false);
32 |
33 | for (int i = 0; i < n; i++) {
34 | cin >> nums[i];
35 | }
36 |
37 | dfs(0, 0, 0);
38 | cout << ans << endl;
39 | return 0;
40 | }如果输入数据中存在重复数字,则重复数字的数量不会影响输出结果。( )
正确答案错误
程序按数组位置选择元素,数值相同的位置仍代表不同选择,因此重复数字的数量会改变方案数。
去掉 `nums.resize(n);` 和 `used.resize(n, false);` 这两行代码,不会影响程序的正常运行。( )
正确答案错误
代码通过下标写入 `nums[i]` 和访问 `used[pos]`;删除两次 `resize` 后两个 vector 为空,会发生越界访问。
如果 , 个数为 1~10 的任意排列,则输出结果是 。( )
正确答案正确
1~10 含 5 个奇数和 5 个偶数;两数之和为偶数需同奇偶,方案数为 inom{5}{2}+inom{5}{2}=2inom{5}{2}。
如果输入的 为 0,则程序的输出结果为( )。
正确答案B
当 时首次调用已满足 `count == k`,且初始和 0 为偶数,因此 `ans` 加 1 后返回,输出 1。
程序的时间复杂度是( )。
正确答案C
每个元素都有选或不选两个分支;在最坏情况下会遍历指数数量的状态,所以时间复杂度为 。
(计数排序)输入 个取值在 到 之间的整数,按从小到大的顺序输出。保证 ,。
1 | #include <iostream>
2 | #include <vector>
3 | using namespace std;
4 | int main() {
5 | int n, k;
6 | cin >> n >> k;
7 | vector<int> cnt(①, 0);
8 | for (int i = 0; i < n; ++i) {
9 | int x;
10 | cin >> x;
11 | ②;
12 | }
13 | bool first = true;
14 | for (int v = 0; ③; ++v) {
15 | while (④) {
16 | if (!first) cout << ' ';
17 | cout << v;
18 | first = false;
19 | ⑤;
20 | }
21 | }
22 | cout << '\n';
23 | return 0;
24 | }① 处应填( )。
k - 1kn + 1k + 1正确答案D
需要使用下标 0 到 k,共 k+1 个位置,所以计数数组长度应为 `k+1`。
② 处应填( )。
++cnt[i]cnt[x] = 1++cnt[x]++x正确答案C
读入数值 x 后,应把它对应的计数 `cnt[x]` 加 1。
③ 处应填( )。
v < nv < kv <= kv <= n正确答案C
输入值可能等于 k,所以输出阶段必须枚举 `v<=k`。
④ 处应填( )。
cnt[v] > 0cnt[v] < 0v < cnt[v]first正确答案A
只要值 v 的剩余出现次数仍大于 0,就应继续输出它。
⑤ 处应填( )。
++cnt[v]--cnt[v]--v++n正确答案B
每输出一次 v,就应把它的剩余计数减 1,即执行 `--cnt[v]`。
波动序列指序列中的元素值交替上升和下降,最长波动子序列是已有的序列中满足这种波动性质的最长子序列。
1 | #include <iostream>
2 | #include <vector>
3 | #include <algorithm>
4 | #define N 1009
5 | using namespace std;
6 | int n;
7 | int dp[N][2];
8 | int main() {
9 | cin >> n;
10 | vector<int> nums(n);
11 | for (int i = 0; i < n; i++) {
12 | cin >> nums[i];
13 | }
14 |
15 | ①
16 | for (int i = 1; i < n; i++) {
17 | for (int j = 0; ②; j++) {
18 | if (③) {
19 | int tmp = dp[j][1] + 1;
20 | if (tmp > dp[i][0]) {
21 | dp[i][0] = tmp;
22 | }
23 | }
24 | else if (nums[i] < nums[j]) {
25 | int tmp = ④;
26 | if (tmp > dp[i][1]) {
27 | dp[i][1] = tmp;
28 | }
29 | }
30 | }
31 | }
32 |
33 |
34 | int max_Len = 1;
35 | for (int i = 1; i < n; i++) {
36 | max_Len = max(max_Len, ⑤);
37 | }
38 |
39 | cout << max_Len << endl;
40 |
41 | return 0;
42 | }① 处应填( )。
memset(dp, 1, sizeof(dp));memset(dp, 0x3f, sizeof(dp));fill(dp, dp + n * 2, 1);fill(dp[0], dp[0] + n * 2, 1);正确答案D
`dp` 的 个连续整数都应初始化为 1,`fill(dp[0], dp[0] + n * 2, 1)` 能完成该操作。
② 处应填( )。
j < nj <= nj < ij <= i正确答案C
计算第 个位置的状态时,只能从它之前的下标转移,因此应枚举 `j < i`。
③ 处应填( )。
nums[i] > nums[j]nums[i] >= nums[j]nums[j] > nums[i]nums[j] >= nums[i]正确答案A
后续更新 `dp[i][0]` 使用的是以下降结束的 `dp[j][1]`,因此当前一步必须上升,即 `nums[i] > nums[j]`。
④ 处应填( )。
dp[i][0] + 1dp[i][1] + 1dp[j][0] + 1dp[j][1] + 1正确答案C
当 `nums[i] < nums[j]` 时形成一次下降,应由以前一个位置上升结束的状态转移,故为 `dp[j][0] + 1`。
⑤ 处应填( )。
dp[i][0]dp[i][1]max(dp[i][0], dp[i][1])min(dp[i][0], dp[i][1])正确答案C
以位置 结尾的最优长度可能最后上升,也可能最后下降,应取 `max(dp[i][0], dp[i][1])`。