试卷解析 · 理解每一步
普及组 CSP-J 2026 初赛模拟卷 8
CSPJ-2026-R1-Mock-8
试卷解析总览,可直接查看每题答案与解析。
第 1 题(单选题,2 分)
CCF 的中文全称是( )。
正确答案C
解析详情
CCF 是 China Computer Federation 的缩写,中文名称为“中国计算机学会”。
第 2 题(单选题,2 分)
在 Linux 终端中,若当前目录下有一个空目录 `tmp`,删除该空目录可以使用命令( )。
正确答案D
解析详情
`rmdir tmp` 用于删除空目录;`mkdir` 创建目录,`touch` 创建文件或更新时间戳,`cp` 用于复制。
第 3 题(单选题,2 分)
表达式 `a * (b + c) * d` 的后缀形式是( )。
正确答案B
解析详情
先把 `b+c` 写成 `b c +`,再依次与 `a`、`d` 相乘,得到 `a b c + * d *`。后缀式中运算符出现在两个操作数之后,不需要括号。
第 4 题(单选题,2 分)
下列名称中,不能作为 C++ 变量名的是( )。
正确答案A
解析详情
C++ 标识符可以由字母、数字和下划线组成,但不能以数字开头,因此 `2sum` 非法。
第 5 题(单选题,2 分)
二进制数 `00101100` 和 `00010101` 的和是( )。
正确答案B
解析详情
`00101100` 为 44,`00010101` 为 21,二者之和为 65;,对应八位二进制数 `01000001`。
第 6 题(单选题,2 分)
微型计算机在工作中电源突然中断,再次通电后数据不能恢复的是( )。
正确答案C
解析详情
RAM 依靠持续供电保存当前数据,断电后其中的信息会丢失;ROM 和硬盘属于非易失性存储,重新通电后原有内容仍可保留。
第 7 题(单选题,2 分)
从一个 的棋盘(不可旋转)中选取不在同一行也不在同一列上的两个方格(不计顺序),有( )种方法。
正确答案A
解析详情
任取两格有 种;同一行有 种,同一列也有 24 种,且两类不会重合。因此所求为 。
第 8 题(单选题,2 分)
执行下面的 C++ 代码后,输出结果是( )。
int x = 3;
int &r = x;
r += 4;
cout << x;正确答案D
解析详情
`r` 是变量 `x` 的引用,对 `r` 加 4 就是直接把 `x` 从 3 修改为 7,因此输出 7。
第 9 题(单选题,2 分)
同时掷出 3 枚完全相同的六面骰子,每枚骰子上有 1 到 6 的数字。将得到的点数排序后,有( )种不同的结果。
正确答案B
解析详情
排序后的结果等价于从 1~6 中可重复地选 3 个数且不计顺序。由可重复组合公式,结果数为 。
第 10 题(单选题,2 分)
一个初始为空的队列依次执行 `push(4)`、`push(7)`、`pop()`、`push(9)`。此时从队首到队尾的元素依次为( )。
正确答案A
解析详情
队列先进先出。压入 4、7 后弹出队首 4,再压入 9,剩余元素从队首到队尾为 7、9。
第 11 题(单选题,2 分)
采用 8 位二进制补码表示的有符号整数中,最小值的编码是( )。
正确答案A
解析详情
8 位补码能够表示的范围是 到 。最小值 -128 的补码编码为 `10000000`。
第 12 题(单选题,2 分)
前序遍历序列与后序遍历序列相同的二叉树为( )。
正确答案B
解析详情
前序遍历先访问根,后序遍历最后访问根;只要还有其他节点,两序列中根的位置就不同。因而两序列完全相同只可能是仅有根节点的二叉树。
第 13 题(单选题,2 分)
下面有关数制的式子中,正确的是( )。
正确答案B
解析详情
八进制中 。例如 ,并不是 ,故 B 正确。
第 14 题(单选题,2 分)
若对于所有规模为 的输入,一个算法均恰好进行( )次运算,则可以说该算法的时间复杂度为 。
正确答案A
解析详情
,与 只差常数因子,所以属于 。其余各项与 的比值分别为 、 和 ,都不受常数约束。
第 15 题(单选题,2 分)
若 ,,,则随着 的增大, 将接近于( )。
正确答案B
解析详情
特征方程为 ,根为 和 。由 得 ;振荡项趋于 0,所以极限为 。
二、阅读程序(1)
1 | #include <iostream>
2 | using namespace std;
3 | int rSum(int j) {
4 | int sum = 0;
5 | while (j != 0) {
6 | sum = sum * 10 + (j % 10);
7 | j = j / 10;
8 | }
9 | return sum;
10 | }
11 | int main() {
12 | int n, m;
13 | cin >> n >> m; // 保证输入为正整数,但不大于 10^9
14 | for (int i = n; i < m; i++)
15 | if (i == rSum(i)) cout << i << ' ';
16 | return 0;
17 | }第 16 题(判断题,1 分)
主函数中的 `for` 循环总共执行 次。( )
正确答案错误
解析详情
循环变量取满足 的整数;仅当 时才执行 次。输入没有保证 ,若 ,循环执行 0 次而不是负数次。
第 17 题(判断题,2 分)
`rSum` 这个函数的返回值 `sum` 一定不会大于 。( )
正确答案错误
解析详情
`rSum` 实际返回十进制数位反转结果,反转后可能变大。例如 `rSum(12)=21`,有 。
第 18 题(判断题,2 分)
若 、 足够大,则输出个数的量级逐渐趋近于 。( )
正确答案正确
解析详情
程序输出十进制回文数。一个不超过 的 位回文数由前 位唯一确定,所需自由位约为总位数的一半,因此累计数量与 同量级。
第 19 题(判断题,2 分)
输入任意两个取值范围为 的整数,输出个数都不超过 100。( )
正确答案正确
解析详情
循环只检查区间 内的整数;当 时,最多检查 到 共 99 个数,输出又只是其中的回文数子集,所以不超过 100。
第 20 题(单选题,3 分)
若输入 `190 230`,总共会输出( )个数。
正确答案D
解析详情
循环检查 。其中满足 `i == rSum(i)` 的数依次为 `191、202、212、222`,共输出 4 个。
第 21 题(单选题,3 分)
假设 和 是相同量级(),则程序的时间复杂度是( )。
正确答案B
解析详情
当 时,外层 `for` 检查 个整数。`rSum(i)` 每次通过除以 10 处理 位,因此总时间为 。
二、阅读程序(2)
1 | #include <iostream>
2 | #include <string>
3 | using namespace std;
4 | int main() {
5 | string s;
6 | char m1, m2;
7 | getline(cin, s);
8 | m1 = ' ';
9 | m2 = ' ';
10 | for (int i = 0; i < s.length(); i++) {
11 | if (s[i] > m1) {
12 | m2 = m1;
13 | m1 = s[i];
14 | } else if (s[i] > m2)
15 | m2 = s[i];
16 | }
17 | cout << int(m1) << ' ' << int(m2) << endl;
18 | return 0;
19 | }第 22 题(判断题,1 分)
`getline()` 会将一整行连带空格一起输入到字符串中。( )
正确答案正确
解析详情
`getline(cin, s)` 读取到换行符为止,行内的空格会作为普通字符存入 `s`,只有作为分隔符的换行符不会存入。
第 23 题(判断题,2 分)
输出的两个整数不可能相同。( )
正确答案错误
解析详情
程序没有要求两个字符互异。若最大字符重复出现,例如输入 `zz`,第一次令 `m1='z'`,第二次会令 `m2='z'`,最终两个整数都为 122。
第 24 题(判断题,2 分)
删去 `else` 这几个字符,则可能出现 的情况。( )
正确答案错误
解析详情
删去 `else` 后,第二个 `if` 也会在更新 `m1` 后执行;此时最多把 `m2` 更新为新的 `m1`。因此始终仍有 `m2<=m1`,不可能出现 `m2>m1`。
第 25 题(判断题,2 分)
若输入长度为 10 且仅含小写字母的随机字符串,则输出结果中 的值越大,其出现的可能性越小。( )
正确答案错误
解析详情
是 10 个字符中允许重复的第二大字符,随机样本通常集中在较大的字母。例如 要求至多一个字符大于 `a`,条件极苛刻;较大的 反而可由更多字符串产生。
第 26 题(单选题,3 分)
维护 `m1` 和 `m2` 的过程最接近( )。
正确答案B
解析详情
每读入一个字符,程序把它插入当前由 `m1、m2` 表示的降序前两名,并在必要时把旧 `m1` 后移到 `m2`。这种逐个插入到已有有序序列的过程最接近插入排序。
第 27 题(单选题,3 分)
若输入 `mxoj is the best online judge`,输出为( )。
正确答案C
解析详情
逐字符维护前两大字符时,字符串中的最大字符是 `x`,ASCII 码为 120;次大字符是 `u`,ASCII 码为 117。因此输出 `120 117`。
二、阅读程序(3)
1 | #include <iostream>
2 | using namespace std;
3 | int n, p, a;
4 | int main() {
5 | cin >> n; // 保证输入在 int 范围内
6 | while (n > 1) {
7 | for (p = 2; p <= n; p++)
8 | if (n % p == 0) break;
9 | for (a = 0; n % p == 0; n /= p) a++;
10 | cout << p << ' ' << a << endl;
11 | }
12 | return 0;
13 | }第 28 题(判断题,2 分)
若输入正整数,则程序在有限步内一定会结束。( )
正确答案正确
解析详情
当 时,内层总能找到一个整除 的 (最迟找到 );随后至少执行一次 `n /= p`,使正整数 严格减小,最终到达 1。
第 29 题(判断题,2 分)
如有输出,输出的 永远是正的。( )
正确答案正确
解析详情
只有找到因子 后才进入第二个 `for`,此时 `n % p == 0` 至少成立一次,所以 `a` 至少从 0 增加到 1 后才输出。
第 30 题(判断题,2 分)
最坏情况下程序的时间复杂度为 。( )
正确答案正确
解析详情
按直接上界估计,外层 `while` 至多执行 轮,每轮寻找因子的 `for` 至多检查 个候选,故可得 上界。实际上每轮会除尽一个质因子,还能给出更紧的上界,但不影响该大 O 断言成立。
第 31 题(判断题,2 分)
输出的 是逐行严格递增的。( )
正确答案正确
解析详情
每次找到当前 的最小因子 后,第二个循环会把该因子的所有幂全部除尽。所以下一轮找到的质因子必然大于当前 ,输出的 逐行严格递增。
第 32 题(单选题,3 分)
若输入 72,则共输出( )个数。
正确答案B
解析详情
。程序对每种不同质因子输出一行,先输出 `2 3`,再输出 `3 2`,因此共输出 2 行结果。
第 33 题(单选题,3 分)
对 依次运行以上程序,输出的总行数最接近( )。
正确答案C
解析详情
对每个 ,输出行数等于其不同质因子个数 。枚举 并累加可得 ;它与 150 相差 21,与 200 相差 29,所以最接近 150。
三、完善程序(1)子矩阵
输入一个 的矩阵 和一个 的矩阵 ,判断 中是否存在与 相等的连续子矩阵;若存在,输出所有子矩阵左上角坐标,否则输出 `There is no answer`。
1 | #include <iostream>
2 | using namespace std;
3 | const int SIZE = 50;
4 | int n1, m1, n2, m2, a[SIZE][SIZE], b[SIZE][SIZE];
5 | int main() {
6 | int i, j, k1, k2;
7 | bool good, haveAns;
8 | cin >> n1 >> m1;
9 | for (i = 1; i <= n1; i++)
10 | for (j = 1; j <= m1; j++) cin >> a[i][j];
11 | cin >> n2 >> m2;
12 | for (i = 1; i <= n2; i++)
13 | for (j = 1; j <= m2; j++) cin >> b[i][j];
14 | ①;
15 | for (i = 1; i <= n1 - n2 + 1; i++)
16 | for (j = 1; j <= ②; j++) {
17 | ③;
18 | for (k1 = 1; k1 <= n2; k1++)
19 | for (k2 = 1; k2 <= m2; k2++) {
20 | if (④ != b[k1][k2])
21 | good = false;
22 | }
23 | if (good) {
24 | cout << i << ' ' << j << endl;
25 | ⑤;
26 | }
27 | }
28 | if (!haveAns)
29 | cout << "There is no answer" << endl;
30 | return 0;
31 | }第 34 题(单选题,3 分)
① 处应填( )。
haveAns = truehaveAns = falsegood = truegood = false正确答案B
解析详情
`haveAns` 记录是否曾找到匹配子矩阵。在开始枚举任何左上角坐标前尚无答案,因此必须初始化为 `false`,之后找到匹配时再改为 `true`。
第 35 题(单选题,3 分)
② 处应填( )。
n1 + n2 - 1m1 - m2 + 1n1 - m1 + 1m1 + m2 - 1正确答案B
解析详情
宽为 的子矩阵若从第 列开始,最右列为 ,需满足 。因此 的上界是 。
第 36 题(单选题,3 分)
③ 处应填( )。
haveAns = truehaveAns = falsegood = truegood = false正确答案C
解析详情
每枚举一个新的左上角 `(i,j)`,都应先假设该候选完全匹配,即令 `good = true`;随后只要发现任一对应元素不等,就把 `good` 置为 `false`。
第 37 题(单选题,3 分)
④ 处应填( )。
a[i + k1 - 1][j + k2 - 1]a[i + k1][j + k2]a[i - k1 - 1][j - k2 - 1]a[i - k1][j - k1]正确答案A
解析详情
`b[k1][k2]` 对应以 `(i,j)` 为左上角的子矩阵第 `k1` 行、第 `k2` 列。由于数组从 1 开始编号,在 `a` 中的位置应为 `a[i+k1-1][j+k2-1]`。
第 38 题(单选题,3 分)
⑤ 处应填( )。
haveAns = truehaveAns = falsegood = truegood = false正确答案A
解析详情
进入 `if (good)` 表明当前子矩阵与 `b` 完全相等,程序已经输出一个答案,所以应执行 `haveAns = true`。这样最后的 `if (!haveAns)` 就不会误报无解。
三、完善程序(2)高精度加法
输入两个位数不超过 100 且首位不是 0 的大整数。使用数组的每个元素存储一位数,输出两数之和。
1 | #include <iostream>
2 | #include <string>
3 | #define SIZE 200
4 | using namespace std;
5 |
6 | int x[2][SIZE]; // x[0]、x[1] 存放两个加数
7 |
8 | void converts(int d, string s) {
9 | int i, len = ①;
10 | for (i = 0; i < len; i++)
11 | x[d][i] = s[len - i - 1] - '0';
12 | }
13 |
14 | void add() {
15 | for (int i = 0; i < SIZE; i++) {
16 | x[0][i] += x[1][i];
17 | if (②) {
18 | x[0][i + 1]++;
19 | ③;
20 | }
21 | }
22 | }
23 |
24 | void print(int d) {
25 | int i;
26 | for (i = SIZE - 1; i > 0; i--)
27 | if (x[d][i]) ④;
28 | for (; i >= 0; i--) cout << x[d][i];
29 | cout << endl;
30 | }
31 |
32 | int main() {
33 | string s1, s2;
34 | cin >> s1 >> s2;
35 | converts(0, s1);
36 | converts(1, s2);
37 | add();
38 | ⑤;
39 | return 0;
40 | }第 39 题(单选题,3 分)
① 处应填( )。
0ds.length()s.length() - 1正确答案C
解析详情
循环需要处理字符串中的每一位,故 `len` 应等于 `s.length()`。随后用 `s[len-i-1]` 从末位向首位读取,使个位存入 `x[d][0]`。
第 40 题(单选题,3 分)
② 处应填( )。
x[0][i] >= 10x[0][i] > 10x[1][i] >= 10x[1][i] > 10正确答案A
解析详情
相加结果保存在 `x[0][i]`;十进制某位达到 10 就必须向 `x[0][i+1]` 进 1,因此条件是 `x[0][i] >= 10`。值恰好为 10 也要进位。
第 41 题(单选题,3 分)
③ 处应填( )。
x[0][i] += 10x[0][i] -= 10x[1][i] += 10x[1][i] -= 10正确答案B
解析详情
发生进位后已经执行 `x[0][i+1]++`,当前位应保留除以 10 的余数。两位十进制数位加进位后最大为 19,所以执行 `x[0][i] -= 10` 即可。
第 42 题(单选题,3 分)
④ 处应填( )。
returncontinuecout << x[d][i]break正确答案D
解析详情
循环从最高下标向下寻找第一个非零数位;找到后应 `break`,保留当前下标 `i`,再由下一循环从该位输出到个位。这样可以跳过所有前导零。
第 43 题(单选题,3 分)
⑤ 处应填( )。
print(0)print(1)print(2)print(3)正确答案A
解析详情
`add()` 将 `x[1]` 的各位累加到 `x[0]`,并把进位也写回 `x[0]`,所以最终和完整存放在第 0 行,应调用 `print(0)`。