GESP 客观题评测系统

试卷解析 · 理解每一步

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

CSPJ-2026-R1-Mock-1

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

一、单项选择题

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

第 1 题(单选题,2 分)

启动计算机引导操作系统是将操作系统( )。

A.
从磁盘调入中央处理器
B.
从内存储器调入高速缓冲存储器
C.
从软盘调入硬盘
D.
从系统盘调入内存储器

正确答案D

解析详情
答案 D操作系统启动过程
思路与推导
  1. 启动引导程序会把系统盘上的操作系统装入内存,CPU 再执行内存中的系统代码,因此选 D。

第 2 题(单选题,2 分)

在 Linux 终端中创建名为 `notes` 的新目录,应使用命令( )。

A.
`touch notes`
B.
`cd notes`
C.
`rm notes`
D.
`mkdir notes`

正确答案D

解析详情
答案 DLinux 目录命令
思路与推导
  1. `mkdir notes` 用于创建目录;`touch` 通常创建普通文件,`cd` 切换目录,`rm` 删除文件。

第 3 题(单选题,2 分)

已知 `bool a=false, b=true`,表达式 `!a && b` 的值为( )。

A.
`true`
B.
`false`
C.
编译错误
D.
无法确定

正确答案A

解析详情
答案 A逻辑运算
思路与推导
  1. `!a` 为 true,再与 b 的 true 进行逻辑与,结果仍为 true。

第 4 题(单选题,2 分)

计算机的运算速度取决于给定时间内其处理器所能处理的数据量。处理器一次能处理的数据量称为字长。已知 64 位的奔腾处理器一次能处理 64 位,相当于( )字节。

A.
88
B.
11
C.
1616
D.
22

正确答案A

解析详情
答案 A位与字节换算
思路与推导
  1. 1 字节等于 8 位,所以 64 位字长相当于 64/8=864/8=8 字节。

第 5 题(单选题,2 分)

算式 (2047)10−(3FF)16+(2000)8(2047)_{10}-(3\mathrm{FF})_{16}+(2000)_8 的结果是( )。

A.
(2048)10(2048)_{10}
B.
(2049)10(2049)_{10}
C.
(3746)8(3746)_8
D.
(1AF7)16(1\mathrm{AF7})_{16}

正确答案A

解析详情
答案 A进制转换
思路与推导
  1. (3FF)16=1023(3\mathrm{FF})_{16}=1023,(2000)8=1024(2000)_8=1024,因此 2047−1023+1024=20482047-1023+1024=2048。

第 6 题(单选题,2 分)

在 C++ 中,表达式 `sizeof(char)` 的结果一定是( )。

A.
1
B.
2
C.
4
D.
取决于操作系统位数

正确答案A

解析详情
答案 AC++ 基本类型
思路与推导
  1. C++ 规定 `sizeof(char)` 恒等于 1 个字节;一个字节包含多少位由实现决定,但结果仍为 1。

第 7 题(单选题,2 分)

设栈 SS 的初始状态为空,现有 5 个元素组成的序列 {1,2,3,4,5}\{1,2,3,4,5\},对该序列在栈 SS 上依次进行如下操作(从序列中的 1 开始,出栈后不再进栈):进栈、出栈、进栈、进栈、出栈、进栈、出栈、进栈。出栈的元素序列是( )。

A.
{5,4,3,2,1}\{5,4,3,2,1\}
B.
{2,3}\{2,3\}
C.
{2,3,4}\{2,3,4\}
D.
{1,3,4}\{1,3,4\}

正确答案D

解析详情
答案 D栈操作模拟
思路与推导
  1. 依次操作得到:1 入栈后弹出 1;2、3 入栈后弹出 3;4 入栈后弹出 4;最后 5 入栈。因此出栈序列为 {1,3,4}\{1,3,4\}。

第 8 题(单选题,2 分)

在有 nn 个叶节点的哈夫曼树中,节点总数为( )。

A.
不确定
B.
2n−12n-1
C.
2n+12n+1
D.
2n2n

正确答案B

解析详情
答案 B哈夫曼树节点数
思路与推导
  1. 哈夫曼树是严格二叉树,若有 nn 个叶节点,则内部节点有 n−1n-1 个,总节点数为 2n−12n-1。

第 9 题(单选题,2 分)

电线上停着两种鸟(A 和 B),可以看出相邻的两只鸟将电线划分为一个线段。这些线段可分为两类:一类是线段两端的鸟种类相同,另一类是线段两端的鸟种类不同。已知电线的两个端点处恰好停着种类相同的鸟,那么两端的鸟种类不同的线段数目一定是( )。

A.
奇数
B.
偶数
C.
可奇可偶
D.
数目固定

正确答案B

解析详情
答案 B序列相邻变化次数
思路与推导
  1. 沿电线从一端走到另一端,每遇到异种鸟就切换一次种类。两端鸟种相同,切换总次数必为偶数。

第 10 题(单选题,2 分)

从未排序序列中挑选元素,并将其依次放入已排序序列(初始时为空)的一端,这种排序方法称为( )。

A.
插入排序
B.
归并排序
C.
选择排序
D.
快速排序

正确答案C

解析详情
答案 C选择排序
思路与推导
  1. 选择排序每轮从未排序部分选出一个目标元素,并把它放到已排序部分的一端。

第 11 题(单选题,2 分)

对于一棵满二叉树,若其叶节点数为 mm、分支节点数为 LL、总节点数为 nn,则下列关系式恒成立的是( )。

A.
n=L+mn=L+m
B.
L+m=2nL+m=2n
C.
m=L−1m=L-1
D.
n=2L−1n=2L-1

正确答案A

解析详情
答案 A二叉树节点分类
思路与推导
  1. 满二叉树的节点只分为叶节点和分支节点,所以总节点数恒有 n=L+mn=L+m。此外满二叉树满足 m=L+1m=L+1,故 n=2L+1n=2L+1。

第 12 题(单选题,2 分)

执行 `string s = "CSPJ"; cout << s.size();` 后输出( )。

A.
3
B.
4
C.
5
D.
编译错误

正确答案B

解析详情
答案 Bstring 长度
思路与推导
  1. 字符串 `CSPJ` 包含 4 个字符,`size()` 返回 4。

第 13 题(单选题,2 分)

已经编译得到程序 `main`,希望从 `input.txt` 读入并把输出写入 `output.txt`,正确的 Linux 命令是( )。

A.
`./main output.txt input.txt`
B.
`./main < input.txt > output.txt`
C.
`input.txt | output.txt | ./main`
D.
`g++ input.txt -o output.txt`

正确答案B

解析详情
答案 B输入输出重定向
思路与推导
  1. `< input.txt` 把标准输入重定向到文件,`> output.txt` 把标准输出重定向到文件。

第 14 题(单选题,2 分)

已知元素 (8,25,14,87,51,90,6,19,20)(8,25,14,87,51,90,6,19,20),这些元素以( )的顺序全部入栈,再全部出栈,可使栈的出栈顺序满足:8 在 51 之前;90 在 87 之后;20 在 14 之后;25 在 6 之前;19 在 90 之后。

A.
20,6,8,51,90,25,14,19,8720,6,8,51,90,25,14,19,87
B.
51,6,19,20,14,8,87,90,2551,6,19,20,14,8,87,90,25
C.
19,20,90,8,6,25,51,14,8719,20,90,8,6,25,51,14,87
D.
6,25,51,8,20,19,90,87,146,25,51,8,20,19,90,87,14

正确答案D

解析详情
答案 D栈的后进先出
思路与推导
  1. 全部入栈后再全部出栈,出栈顺序是入栈序列的逆序。D 逆序后为 14,87,90,19,20,8,51,25,614,87,90,19,20,8,51,25,6,逐一满足题目给出的五个先后条件。

第 15 题(单选题,2 分)

假设我们用向量 d=(a1,a2,⋯ ,a5)\boldsymbol{d}=(a_1,a_2,\cdots,a_5) 表示无向连通图 GG 的 5 个顶点的度数,下面给出的( )组 d\boldsymbol{d} 值合理。

A.
(2,2,2,2,2)(2,2,2,2,2)
B.
(1,2,2,1,1)(1,2,2,1,1)
C.
(3,3,3,2,2)(3,3,3,2,2)
D.
(5,4,3,2,1)(5,4,3,2,1)

正确答案A

解析详情
答案 A无向图度数序列
思路与推导
  1. 无向图度数和必须为偶数,且 5 个顶点的简单图中每个度数不超过 4。A 可由一个 5 阶环实现;其余选项或度数和为奇数,或出现度数 5。

二、阅读程序(1)

程序输入不超过数组或字符串定义的范围;判断题正确填 ✓,错误填 ✗。

 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 | }

第 16 题(判断题,2 分)

输入 97 时,输出为 `NO`。

正确答案错误

解析详情
答案 错误素数判断程序
思路与推导
  1. 97 没有不超过 97\sqrt{97} 的整数因子,`IsPrime(97)` 返回 `true`,程序输出 `YES`。

第 17 题(判断题,2 分)

输入 119 时,输出为 `YES`。

正确答案错误

解析详情
答案 错误合数判定
思路与推导
  1. 119=7×17119=7\times17,循环在 `i=7` 时找到因子并返回 `false`,程序输出 `NO`。

第 18 题(判断题,2 分)

若将第 5 行的 `<=` 改成 `<`,程序输出不会改变。

正确答案错误

解析详情
答案 错误试除法边界
思路与推导
  1. 若把 `<=` 改为 `<`,完全平方数的平方根不会被试除。例如 49 将跳过因子 7,从而被误判为素数。

第 19 题(判断题,2 分)

当程序执行第 8 行时,`i` 的值为 `sqrt(num)`。

正确答案错误

解析详情
答案 错误变量作用域
思路与推导
  1. `i` 在第 5 行 `for` 初始化语句中定义,只在该循环内有效;执行第 8 行时已经不存在可访问的变量 `i`。

第 20 题(单选题,3 分)

最坏情况下,此程序的时间复杂度是( )。

A.
O(num)O(\mathrm{num})
B.
O(num2)O(\mathrm{num}^2)
C.
O(num)O(\sqrt{\mathrm{num}})
D.
O(log⁡num)O(\log \mathrm{num})

正确答案C

解析详情
答案 C试除法时间复杂度
思路与推导
  1. 最坏情况下循环从 2 检查到 num\sqrt{\mathrm{num}},迭代次数与 num\sqrt{\mathrm{num}} 同阶,因此复杂度为 O(num)O(\sqrt{\mathrm{num}})。

第 21 题(单选题,3 分)

若输入为 20 以内的正整数,则输出 `YES` 的概率是( )。

A.
0.450.45
B.
0.40.4
C.
0.50.5
D.
0.350.35

正确答案A

解析详情
答案 A程序边界条件与概率
思路与推导
  1. 1 到 20 中有 8 个素数;该程序还会把 1 误判为素数,所以共有 9 个输入输出 `YES`,概率为 9/20=0.459/20=0.45。

二、阅读程序(2)

 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 | }

第 22 题(判断题,2 分)

将第 9 行和第 11 行中的圆括号去掉,程序输出不变。

正确答案正确

解析详情
答案 正确运算符优先级与结合性
思路与推导
  1. 去掉第 9、11 行乘法外层的括号后,表达式分别成为 `res * x % mod` 和 `x * x % mod`;乘法与取模同级且从左到右结合,结果不变。

第 23 题(判断题,2 分)

将第 12 行的 `mi >>= 1` 改为 `mi *= 0.5`,程序输出不变。

正确答案正确

解析详情
答案 正确快速幂指数折半
思路与推导
  1. 在题目预期的非负整数范围内,`mi >>= 1` 与整型变量执行 `mi *= 0.5` 都得到向下取整的 mi/2mi/2,循环过程不变。

第 24 题(判断题,2 分)

若输入 `4 4`,输出为 78。

正确答案错误

解析详情
答案 错误快速幂程序求值
思路与推导
  1. 输入 `4 4` 时,34+3×(−1)4=81+3=843^4+3\times(-1)^4=81+3=84,取模后仍为 84,并非 78。

第 25 题(判断题,2 分)

此程序的时间复杂度为 O(log⁡n)O(\log n)。

正确答案正确

解析详情
答案 正确快速幂复杂度
思路与推导
  1. 循环每次把指数 `mi` 折半,迭代次数为 O(log⁡n)O(\log n);主函数中的其余运算均为常数时间。

第 26 题(单选题,4 分)

若输入 `3 4`,输出为( )。

A.
88
B.
1212
C.
1818
D.
1919

正确答案B

解析详情
答案 B程序分支模拟
思路与推导
  1. 输入 `3 4` 后满足 `n == 3`,直接输出 c(c−1)=4×3=12c(c-1)=4\times3=12。

二、阅读程序(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 | }

第 27 题(判断题,2 分)

程序结束时,对任意 1≤i≤n1 \le i \le n,都有 `mark[i] = 0`。

正确答案正确

解析详情
答案 正确回溯状态恢复
思路与推导
  1. 每次递归前把 `mark[i]` 设为 `true`,递归返回后又设回 `false`;所有调用结束时数组恢复到初始的全 0 状态。

第 28 题(判断题,2 分)

若 n<rn<r,则程序无输出。

正确答案正确

解析详情
答案 正确排列枚举边界
思路与推导
  1. 当 n<rn<r 时,最多只能选出 nn 个互不相同的数字,递归无法到达 `x == r` 的打印条件,因此没有输出。

第 29 题(判断题,2 分)

若输入 `4 3`,则输出中数字 1 和 2 的个数不同。

正确答案错误

解析详情
答案 错误排列中的对称计数
思路与推导
  1. 输入 `4 3` 会枚举所有 4 个数取 3 个的排列。由对称性,每个数字出现的总次数相同,所以数字 1 和 2 的个数相同。

第 30 题(判断题,2 分)

此程序的时间复杂度为 O(n)O(n)。

正确答案错误

解析详情
答案 错误回溯枚举复杂度
思路与推导
  1. 程序枚举长度为 rr 的排列,输出规模为 AnrA_n^r;当 r=nr=n 时达到 n!n! 量级,显然不是 O(n)O(n)。

第 31 题(单选题,3 分)

若输入 `6 3`,则函数 `print` 的执行次数为( )。

A.
6060
B.
120120
C.
66
D.
720720

正确答案B

解析详情
答案 B排列数
思路与推导
  1. 输入 `6 3` 时会打印从 6 个数中依次取 3 个的所有排列,次数为 A63=6×5×4=120A_6^3=6\times5\times4=120。

第 32 题(单选题,3 分)

若输入 `7 4`,则输出的最后一行为( )。

A.
`4567`
B.
`7654`
C.
`4321`
D.
`1234`

正确答案B

解析详情
答案 B字典序枚举
思路与推导
  1. 每层循环都按 1 到 7 的顺序选择数字,因此输出按字典序递增;最大的 4 位排列是 `7654`。

三、完善程序(1)循环队列

(循环队列)使用长度为 NN 的数组实现一个循环队列。约定队列最多保存 N−1N-1 个元素,测试数据保证不会向满队列继续入队,也不会从空队列取元素。

1 | #include <iostream>
2 | using namespace std;
3 | const int N = 1005;
4 | int q[N], head = 0, tail = 0;
5 | bool empty() {
6 |     return ①;
7 | }
8 | void push(int x) {
9 |     ②;
10 |     tail = (tail + 1) % N;
11 | }
12 | int front() {
13 |     return ③;
14 | }
15 | void pop() {
16 |     ④;
17 | }
18 | int main() {
19 |     push(4);
20 |     push(7);
21 |     pop();
22 |     push(9);
23 |     cout << ⑤ << '\n';
24 |     return 0;
25 | }

第 33 题(单选题,3 分)

① 处应填( )。

A.
head == tail
B.
head != tail
C.
head == 0
D.
tail == N

正确答案A

解析详情
答案 A循环队列判空
思路与推导
  1. 本实现用 `head==tail` 表示队列为空。

第 34 题(单选题,3 分)

② 处应填( )。

A.
q[head] = x
B.
q[tail] = x
C.
head = x
D.
tail = x

正确答案B

解析详情
答案 B循环队列入队
思路与推导
  1. 新元素写入当前队尾位置 `q[tail]`,再把 tail 循环后移。

第 35 题(单选题,3 分)

③ 处应填( )。

A.
q[tail]
B.
tail
C.
q[head]
D.
head

正确答案C

解析详情
答案 C循环队列队首
思路与推导
  1. head 指向当前队首元素,所以 `front()` 返回 `q[head]`。

第 36 题(单选题,3 分)

④ 处应填( )。

A.
tail = (tail + 1) % N
B.
head = (head + 1) % N
C.
--tail
D.
head = tail

正确答案B

解析详情
答案 B循环队列出队
思路与推导
  1. 出队删除队首元素,只需把 head 循环后移一格。

第 37 题(单选题,3 分)

⑤ 处应填( )。

A.
empty()
B.
tail
C.
q[tail]
D.
front()

正确答案D

解析详情
答案 D队列操作模拟
思路与推导
  1. 操作后队列为 7、9,输出队首应调用 `front()`,结果为 7。

三、完善程序(2)二维前缀和

(二维前缀和)给定一个 n×mn\times m 的整数矩阵,回答 qq 次子矩形元素和查询。每次给出左上角 (x1,y1)(x_1,y_1) 和右下角 (x2,y2)(x_2,y_2),坐标均从 1 开始。

1 | #include <iostream>
2 | using namespace std;
3 | long long a[505][505], s[505][505];
4 | int main() {
5 |     int n, m, q;
6 |     cin >> n >> m >> q;
7 |     for (int i = 1; i <= ①; ++i) {
8 |         for (int j = 1; j <= m; ++j) {
9 |             cin >> a[i][j];
10 |             s[i][j] = ②;
11 |         }
12 |     }
13 |     while (③--) {
14 |         int x1, y1, x2, y2;
15 |         cin >> x1 >> y1 >> x2 >> y2;
16 |         int up = ④;
17 |         cout << ⑤ << '\n';
18 |     }
19 |     return 0;
20 | }

第 38 题(单选题,3 分)

① 处应填( )。

A.
m
B.
n
C.
q
D.
n * m

正确答案B

解析详情
答案 B矩阵行枚举
思路与推导
  1. 外层循环枚举矩阵的 n 行,因此条件上界应为 n。

第 39 题(单选题,3 分)

② 处应填( )。

A.
a[i][j] + s[i - 1][j] + s[i][j - 1] - s[i - 1][j - 1]
B.
a[i][j] + s[i - 1][j - 1]
C.
s[i - 1][j] + s[i][j - 1]
D.
a[i][j]

正确答案A

解析详情
答案 A二维前缀和构造
思路与推导
  1. 当前前缀和等于当前元素加上上方和左方前缀,再减去被重复计算的左上前缀。

第 40 题(单选题,3 分)

③ 处应填( )。

A.
q
B.
n
C.
m
D.
n + m

正确答案A

解析详情
答案 A查询循环
思路与推导
  1. 共有 q 次子矩形查询,因此使用 `while(q--)`。

第 41 题(单选题,3 分)

④ 处应填( )。

A.
x1 + 1
B.
x2 - 1
C.
x1 - 1
D.
x2 + 1

正确答案C

解析详情
答案 C二维区间边界
思路与推导
  1. 查询矩形上方的前缀区域结束于第 `x1-1` 行,因此令 `up=x1-1`。

第 42 题(单选题,3 分)

⑤ 处应填( )。

A.
s[x2][y2]
B.
s[x2][y2] - s[up][y2]
C.
s[x2][y2] - s[up][y2] - s[x2][y1 - 1]
D.
s[x2][y2] - s[up][y2] - s[x2][y1 - 1] + s[up][y1 - 1]

正确答案D

解析详情
答案 D二维前缀和查询
思路与推导
  1. 用大前缀减去上方和左方区域后,左上区域被减了两次,需要加回一次。