一、单项选择题
(共 15 题,每题 2 分,共计 30 分;每题有且仅有一个正确选项)
CSPJ-2026-R1-Mock-1
试卷解析总览,可直接查看每题答案与解析。
(共 15 题,每题 2 分,共计 30 分;每题有且仅有一个正确选项)
启动计算机引导操作系统是将操作系统( )。
正确答案D
【答案】D
【考点】操作系统启动过程
【解析】 启动引导程序会把系统盘上的操作系统装入内存,CPU 再执行内存中的系统代码,因此选 D。
【易错点】CPU 不能直接把磁盘内容当作正在执行的操作系统。
Windows 9x 是一种( )操作系统。
正确答案D
【答案】D
【考点】操作系统类型
【解析】 Windows 9x 提供图形用户界面,并允许多个任务并发运行,属于多任务图形方式操作系统。
【易错点】不要把图形界面与单任务运行方式混为一谈。
在 点阵的字模中,汉字“一”与“编”的字模占用字节数分别是( )。
正确答案A
【答案】A
【考点】点阵字模存储量
【解析】 每个汉字的字模都占 位,即 字节;字形复杂度不影响点阵存储量。
【易错点】字节数由点阵尺寸决定,不由汉字笔画数决定。
计算机的运算速度取决于给定时间内其处理器所能处理的数据量。处理器一次能处理的数据量称为字长。已知 64 位的奔腾处理器一次能处理 64 位,相当于( )字节。
正确答案A
【答案】A
【考点】位与字节换算
【解析】 1 字节等于 8 位,所以 64 位字长相当于 字节。
【易错点】位(bit)和字节(byte)的换算比例是 8:1。
算式 的结果是( )。
正确答案A
【答案】A
【考点】进制转换
【解析】 ,,因此 。
【易错点】十六进制中的 F 表示 15,八进制每一位的权是 8 的幂。
计算机的运算速度可以用 MIPS 来描述,它的含义是( )。
正确答案A
【答案】A
【考点】MIPS 含义
【解析】 MIPS 是 Million Instructions Per Second 的缩写,表示每秒执行百万条指令。
【易错点】MIPS 衡量的是指令执行数量,不是字符处理数量。
设栈 的初始状态为空,现有 5 个元素组成的序列 ,对该序列在栈 上依次进行如下操作(从序列中的 1 开始,出栈后不再进栈):进栈、出栈、进栈、进栈、出栈、进栈、出栈、进栈。出栈的元素序列是( )。
正确答案D
【答案】D
【考点】栈操作模拟
【解析】 依次操作得到:1 入栈后弹出 1;2、3 入栈后弹出 3;4 入栈后弹出 4;最后 5 入栈。因此出栈序列为 。
【易错点】只有题目明确给出“出栈”时才弹出栈顶元素。
在有 个叶节点的哈夫曼树中,节点总数为( )。
正确答案B
【答案】B
【考点】哈夫曼树节点数
【解析】 哈夫曼树是严格二叉树,若有 个叶节点,则内部节点有 个,总节点数为 。
【易错点】不要把叶节点数直接当作树的总结点数。
电线上停着两种鸟(A 和 B),可以看出相邻的两只鸟将电线划分为一个线段。这些线段可分为两类:一类是线段两端的鸟种类相同,另一类是线段两端的鸟种类不同。已知电线的两个端点处恰好停着种类相同的鸟,那么两端的鸟种类不同的线段数目一定是( )。
正确答案B
【答案】B
【考点】序列相邻变化次数
【解析】 沿电线从一端走到另一端,每遇到异种鸟就切换一次种类。两端鸟种相同,切换总次数必为偶数。
【易错点】中间同种鸟的数量不影响“异种相邻”次数的奇偶性。
从未排序序列中挑选元素,并将其依次放入已排序序列(初始时为空)的一端,这种排序方法称为( )。
正确答案C
【答案】C
【考点】选择排序
【解析】 选择排序每轮从未排序部分选出一个目标元素,并把它放到已排序部分的一端。
【易错点】插入排序是把当前元素插入已有序列的适当位置,描述重点不同。
对于一棵满二叉树,若其叶节点数为 、分支节点数为 、总节点数为 ,则下列关系式恒成立的是( )。
正确答案A
【答案】A
【考点】二叉树节点分类
【解析】 满二叉树的节点只分为叶节点和分支节点,所以总节点数恒有 。此外满二叉树满足 ,故 。
【易错点】由 推导总节点数时符号容易写反。
以下不是操作系统名字的是( )。
正确答案B
【答案】B
【考点】操作系统常识
【解析】 Windows XP、Linux 和 OS/2 都是操作系统;Arch/Info 是地理信息系统相关软件,不是操作系统。
【易错点】不要仅凭名称中含有斜杠就判断软件类别。
以下不是个人计算机的硬件组成部分的是( )。
正确答案B
【答案】B
【考点】计算机硬件组成
【解析】 主板、总线和硬盘都是实体硬件;虚拟内存是操作系统利用存储空间形成的内存管理机制。
【易错点】“内存”一词不代表虚拟内存本身是物理硬件。
已知元素 ,这些元素以( )的顺序全部入栈,再全部出栈,可使栈的出栈顺序满足:8 在 51 之前;90 在 87 之后;20 在 14 之后;25 在 6 之前;19 在 90 之后。
正确答案D
【答案】D
【考点】栈的后进先出
【解析】 全部入栈后再全部出栈,出栈顺序是入栈序列的逆序。D 逆序后为 ,逐一满足题目给出的五个先后条件。
【易错点】应在逆序后的出栈序列上核对全部条件。
假设我们用向量 表示无向连通图 的 5 个顶点的度数,下面给出的( )组 值合理。
正确答案A
【答案】A
【考点】无向图度数序列
【解析】 无向图度数和必须为偶数,且 5 个顶点的简单图中每个度数不超过 4。A 可由一个 5 阶环实现;其余选项或度数和为奇数,或出现度数 5。
【易错点】度数和为偶数只是必要条件,还要检查度数上界和可实现性。
程序输入不超过数组或字符串定义的范围;判断题正确填 ✓,错误填 ✗。
1 | #include <iostream>
2 | #include <cmath>
3 | using namespace std;
4 | bool IsPrime(int num) {
5 | for (int i = 2; i <= sqrt(num); i++) {
6 | if (num % i == 0) return false;
7 | }
8 | return true;
9 | }
10 | int main() {
11 | int num = 0;
12 | cin >> num;
13 | if (IsPrime(num)) cout << "YES" << endl;
14 | else cout << "NO" << endl;
15 | return 0;
16 | }输入 97 时,输出为 `NO`。
正确答案错误
【答案】错误
【考点】素数判断程序
【解析】 97 没有不超过 的整数因子,`IsPrime(97)` 返回 `true`,程序输出 `YES`。
【易错点】题目判断的是实际输出,不是题干给出的预期文本。
输入 119 时,输出为 `YES`。
正确答案错误
【答案】错误
【考点】合数判定
【解析】 ,循环在 `i=7` 时找到因子并返回 `false`,程序输出 `NO`。
【易错点】只试除较小的 2、3、5 不足以判定 119 为素数。
若将第 5 行的 `<=` 改成 `<`,程序输出不会改变。
正确答案错误
【答案】错误
【考点】试除法边界
【解析】 若把 `<=` 改为 `<`,完全平方数的平方根不会被试除。例如 49 将跳过因子 7,从而被误判为素数。
【易错点】试除上界必须包含平方根本身。
当程序执行第 8 行时,`i` 的值为 `sqrt(num)`。
正确答案错误
【答案】错误
【考点】变量作用域
【解析】 `i` 在第 5 行 `for` 初始化语句中定义,只在该循环内有效;执行第 8 行时已经不存在可访问的变量 `i`。
【易错点】循环结束后的数学终值不等于变量在作用域外仍然存在。
最坏情况下,此程序的时间复杂度是( )。
正确答案C
【答案】C
【考点】试除法时间复杂度
【解析】 最坏情况下循环从 2 检查到 ,迭代次数与 同阶,因此复杂度为 。
【易错点】`sqrt(num)` 只出现一次,不能再额外开一次平方根。
若输入为 20 以内的正整数,则输出 `YES` 的概率是( )。
正确答案A
【答案】A
【考点】程序边界条件与概率
【解析】 1 到 20 中有 8 个素数;该程序还会把 1 误判为素数,所以共有 9 个输入输出 `YES`,概率为 。
【易错点】必须按给定程序计算,不能直接只数数学意义上的素数。
1 | #include <bits/stdc++.h>
2 | using namespace std;
3 | const int mod = 2048;
4 | long long c, n;
5 | long long kasumi(long long x, long long mi) {
6 | long long res = 1;
7 | while (mi) {
8 | if (mi & 1) {
9 | res = (res * x) % mod;
10 | }
11 | x = (x * x) % mod;
12 | mi >>= 1;
13 | }
14 | return res;
15 | }
16 | int main() {
17 | cin >> n >> c;
18 | if (n == 3) {
19 | printf("%lld", c * (c - 1));
20 | return 0;
21 | }
22 | long long ans = ((kasumi(c - 1, n) + (c - 1) * kasumi(-1, n)) % mod + mod) % mod;
23 | cout << ans << endl;
24 | return 0;
25 | }将第 9 行和第 11 行中的圆括号去掉,程序输出不变。
正确答案正确
【答案】正确
【考点】运算符优先级与结合性
【解析】 去掉第 9、11 行乘法外层的括号后,表达式分别成为 `res * x % mod` 和 `x * x % mod`;乘法与取模同级且从左到右结合,结果不变。
【易错点】这里去掉的是乘法括号,不是整个取模结构。
将第 12 行的 `mi >>= 1` 改为 `mi *= 0.5`,程序输出不变。
正确答案正确
【答案】正确
【考点】快速幂指数折半
【解析】 在题目预期的非负整数范围内,`mi >>= 1` 与整型变量执行 `mi *= 0.5` 都得到向下取整的 ,循环过程不变。
【易错点】该结论依赖题目按常规整数范围讨论,不要把右移误解为除以 1。
若输入 `4 4`,输出为 78。
正确答案错误
【答案】错误
【考点】快速幂程序求值
【解析】 输入 `4 4` 时,,取模后仍为 84,并非 78。
【易错点】输入顺序是先读 `n` 再读 `c`。
此程序的时间复杂度为 。
正确答案正确
【答案】正确
【考点】快速幂复杂度
【解析】 循环每次把指数 `mi` 折半,迭代次数为 ;主函数中的其余运算均为常数时间。
【易错点】快速幂不是执行 次乘法。
若输入 `3 4`,输出为( )。
正确答案B
【答案】B
【考点】程序分支模拟
【解析】 输入 `3 4` 后满足 `n == 3`,直接输出 。
【易错点】命中特判后立即返回,不会执行后面的通用公式。
1 | #include <cstdio>
2 | int n, r, num[10000];
3 | bool mark[10000];
4 | void print() {
5 | for (int i = 1; i <= r; i++)
6 | printf("%d", num[i]);
7 | printf("\n");
8 | }
9 | void search(int x) {
10 | for (int i = 1; i <= n; i++)
11 | if (!mark[i]) {
12 | num[x] = i;
13 | mark[i] = true;
14 | if (x == r) print();
15 | search(x + 1);
16 | mark[i] = false;
17 | }
18 | }
19 | int main() {
20 | scanf("%d%d", &n, &r);
21 | search(1);
22 | }程序结束时,对任意 ,都有 `mark[i] = 0`。
正确答案正确
【答案】正确
【考点】回溯状态恢复
【解析】 每次递归前把 `mark[i]` 设为 `true`,递归返回后又设回 `false`;所有调用结束时数组恢复到初始的全 0 状态。
【易错点】要观察递归调用之后的回溯语句。
若 ,则程序无输出。
正确答案正确
【答案】正确
【考点】排列枚举边界
【解析】 当 时,最多只能选出 个互不相同的数字,递归无法到达 `x == r` 的打印条件,因此没有输出。
【易错点】程序不允许重复选择已被 `mark` 的数字。
若输入 `4 3`,则输出中数字 1 和 2 的个数不同。
正确答案错误
【答案】错误
【考点】排列中的对称计数
【解析】 输入 `4 3` 会枚举所有 4 个数取 3 个的排列。由对称性,每个数字出现的总次数相同,所以数字 1 和 2 的个数相同。
【易错点】不能只观察输出的前几行判断整体出现次数。
此程序的时间复杂度为 。
正确答案错误
【答案】错误
【考点】回溯枚举复杂度
【解析】 程序枚举长度为 的排列,输出规模为 ;当 时达到 量级,显然不是 。
【易错点】递归层数是 ,但分支数会产生大量排列。
若输入 `6 3`,则函数 `print` 的执行次数为( )。
正确答案B
【答案】B
【考点】排列数
【解析】 输入 `6 3` 时会打印从 6 个数中依次取 3 个的所有排列,次数为 。
【易错点】顺序不同算不同结果,应使用排列数而不是组合数。
若输入 `7 4`,则输出的最后一行为( )。
正确答案B
【答案】B
【考点】字典序枚举
【解析】 每层循环都按 1 到 7 的顺序选择数字,因此输出按字典序递增;最大的 4 位排列是 `7654`。
【易错点】最后一行不是把全部 7 个数字逆序,只取前 4 个位置。
Kruskal 求最小生成树的思想:首先将 个点看作 个独立的集合,将所有边排序(从小到大)。然后按排好的顺序枚举每一条边,判断这条边连接的两个点是否属于同一集合。若不属于同一集合,则将这条边加入最小生成树,并将两个点所在的集合合并为一个集合。若属于同一集合,则跳过。直到找到 条边为止。
1 | #include <iostream>
2 | #include <algorithm>
3 | using namespace std;
4 | struct point { int x, y, v; } a[10000];
5 | int cmp(const point &a, const point &b) {
6 | if (①) return 1;
7 | return 0;
8 | }
9 | int fat[101];
10 | int father(int x) {
11 | if (fat[x] != x) return fat[x] = ②;
12 | return fat[x];
13 | }
14 | void unionn(int x, int y) {
15 | int fa = father(x), fb = father(y);
16 | if (fa != fb) fat[fa] = fb;
17 | }
18 | int main() {
19 | int i, j, n, m, k = 0, ans = 0, cnt = 0;
20 | cin >> n;
21 | for (i = 1; i <= n; i++)
22 | for (j = 1; j <= n; j++) {
23 | cin >> m;
24 | if (m != 0) {
25 | k++; a[k].x = i; a[k].y = j; a[k].v = m;
26 | }
27 | }
28 | sort(a + 1, a + 1 + k, ③);
29 | for (i = 1; i <= n; i++) fat[i] = i;
30 | for (i = 1; i <= k; i++) {
31 | if (father(a[i].x) != ④) {
32 | ans += a[i].v;
33 | unionn(a[i].x, a[i].y);
34 | cnt++;
35 | }
36 | if (⑤) break;
37 | }
38 | cout << ans << endl;
39 | return 0;
40 | }① 处应填( )。
a.v < b.va.v > b.va.v >= b.va.v <= b.v正确答案A
【答案】A
【考点】排序比较函数
【解析】 Kruskal 需要按边权从小到大排序,所以当 `a.v < b.v` 时比较函数应返回真。
【易错点】使用 `<=` 或 `>=` 会破坏严格弱序要求。
② 处应填( )。
father(x)father(fat[x])fat[father(x)]x正确答案B
【答案】B
【考点】并查集路径压缩
【解析】 当 `fat[x] != x` 时,应递归查找父节点的根,即 `father(fat[x])`,并把结果回写给 `fat[x]` 完成路径压缩。
【易错点】递归调用 `father(x)` 会在同一节点上无限递归。
③ 处应填( )。
algorithmpointcmpsizeof(a)正确答案C
【答案】C
【考点】`std::sort` 比较器
【解析】 `sort(first, last, comp)` 的第三个参数应是比较函数,本题已定义的函数名为 `cmp`。
【易错点】头文件名、结构体类型和数组大小都不能充当此处比较器。
④ 处应填( )。
a[i].yfather(a[i].y)fat[a[i].y]a[i].x正确答案B
【答案】B
【考点】Kruskal 判环
【解析】 一条边可以加入生成树的条件是两端点的根不同,因此右侧应写 `father(a[i].y)` 与左端点的根比较。
【易错点】直接比较父节点值不能保证得到集合代表元。
⑤ 处应填( )。
cnt > 0i == 1ans == n - 1cnt == n - 1正确答案D
【答案】D
【考点】生成树边数
【解析】 `cnt` 记录已经选入的边数;含 个顶点的生成树恰有 条边,所以 `cnt == n - 1` 时可停止。
【易错点】`ans` 是边权和,不是已选边数。
欧拉路径问题是指从图中的一个顶点出发,是否能够一次性不回头地走遍所有的边(一次且仅一次)。算法代码如下。
1 | #include <iostream>
2 | using namespace std;
3 | int G[5][5];
4 | int visited[5][5];
5 | int n = 5;
6 | void euler(int u) {
7 | for (int v = 0; v < n; v++) {
8 | if (G[u][v] && ①) {
9 | cout << u << "->" << v << endl;
10 | visited[u][v] = visited[v][u] = ②;
11 | ③
12 | }
13 | }
14 | }
15 | int main() {
16 | G[1][2] = G[2][1] = G[1][3] = ④ = 1;
17 | G[2][4] = G[4][2] = G[3][4] = ⑤ = 1;
18 | euler(1);
19 | return 0;
20 | }① 处应填( )。
G[v][u]!visited[u][v]visited[u][v]visited[v][u]正确答案B
【答案】B
【考点】欧拉路径边访问标记
【解析】 只有邻接矩阵中存在边且该边尚未访问时才应继续,因此条件为 `G[u][v] && !visited[u][v]`。
【易错点】`visited[u][v]` 为真表示已经走过,逻辑方向不能写反。
② 处应填( )。
10uv正确答案A
【答案】A
【考点】无向边标记
【解析】 走过边 后应把两个方向的访问标记同时设为 1,防止之后重复经过同一条无向边。
【易错点】邻接矩阵的两个对称位置表示同一条无向边。
③ 处应填( )。
euler(v);euler(u);G[u][v] = 0;G[v][u] = 0;正确答案A
【答案】A
【考点】欧拉路径递归
【解析】 当前从 `u` 走到相邻顶点 `v` 后,应递归调用 `euler(v)`,继续从新顶点查找未访问边。
【易错点】再次调用 `euler(u)` 会停留在原顶点。
④ 处应填( )。
G[0][1]G[1][0]G[3][1]G[0][3]正确答案C
【答案】C
【考点】无向图邻接矩阵
【解析】 语句已经设置 `G[1][3]`,无向边还需设置其对称位置 `G[3][1]`,因此选 C。
【易错点】对称位置应交换行、列下标。
⑤ 处应填( )。
G[0][2]G[2][0]G[2][1]G[4][3]正确答案D
【答案】D
【考点】无向图邻接矩阵
【解析】 语句已经设置 `G[3][4]`,对应的反向位置是 `G[4][3]`,两者同时赋 1 才表示无向边。
【易错点】不要把已有的边 `G[2][4]` 的对称项与本空混淆。