GESP 客观题评测系统

试卷解析 · 理解每一步

CSP-J 2026 第一轮 AI 模拟卷 1

CSPJ-2026-R1-Mock-AI-1

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

一、单项选择题

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

第 1 题(单选题,2 分)

在 Linux 终端执行命令 `g++ main.cpp -o app`,若编译成功,通常会得到( )。

A.
名为 `main.cpp` 的新源文件
B.
名为 `app` 的可执行文件
C.
名为 `app.cpp` 的目标文件
D.
程序会被自动运行,但不会生成文件

正确答案B

解析详情
答案 Bg++ 编译命令
思路与推导
  1. `-o app` 指定输出文件名为 `app`;编译成功后生成该可执行文件,但不会自动运行。

第 2 题(单选题,2 分)

若一个 `unsigned char` 恰好占 8 个二进制位,则它能表示的整数范围是( )。

A.
−128∼127-128\sim127
B.
0∼1270\sim127
C.
−255∼255-255\sim255
D.
0∼2550\sim255

正确答案D

解析详情
答案 D无符号整数范围
思路与推导
  1. 8 位无符号整数共有 282^8 种状态,因此取值为 00 到 28−1=2552^8-1=255。

第 3 题(单选题,2 分)

执行下列程序后,输出结果是( )。

void change(int &x, int y) {
    x += y;
    y *= 2;
}
int a = 3, b = 4;
change(a, b);
cout << a << " " << b;
A.
`7 4`
B.
`7 8`
C.
`3 8`
D.
`3 4`

正确答案A

解析详情
答案 A引用传参与值传参
思路与推导
  1. `x` 是引用,执行 `x += y` 后 `a` 变为 7;`y` 是值传递,修改副本不会影响 `b`,故输出 `7 4`。

第 4 题(单选题,2 分)

执行下列代码后,字符串 `s` 的值是( )。

string s = "cspj";
s.erase(1, 2);
s.insert(1, "++");
A.
`csp++`
B.
`c++spj`
C.
`c++j`
D.
`cs++j`

正确答案C

解析详情
答案 Cstring 修改操作
思路与推导
  1. `erase(1, 2)` 删除下标 1 开始的 `sp`,得到 `cj`;再在下标 1 插入 `++`,得到 `c++j`。

第 5 题(单选题,2 分)

十进制整数 42 的二进制表示为 `101010`。表达式 `42 ^ (1 << 3)` 的值是( )。

A.
`50`
B.
`46`
C.
`40`
D.
`34`

正确答案D

解析详情
答案 D按位异或
思路与推导
  1. `1 << 3` 等于 8,42 的第 3 位为 1;与 8 异或会把该位翻转为 0,所以结果为 42−8=3442-8=34。

第 6 题(单选题,2 分)

二进制数 (101101)2(101101)_2 与八进制数 (27)8(27)_8 之和,用十六进制表示为( )。

A.
(42)16(42)_{16}
B.
(43)16(43)_{16}
C.
(44)16(44)_{16}
D.
(45)16(45)_{16}

正确答案C

解析详情
答案 C进制转换
思路与推导
  1. (101101)2=45(101101)_2=45,(27)8=23(27)_8=23,两者之和为 68,即十六进制的 (44)16(44)_{16}。

第 7 题(单选题,2 分)

一棵完全二叉树共有 2026 个结点,则其叶结点数为( )。

A.
1012
B.
1013
C.
1014
D.
2026

正确答案B

解析详情
答案 B完全二叉树
思路与推导
  1. 顺序编号为 1 到 2026 时,编号不超过 lfloor2026/2floor=1013lfloor2026/2 floor=1013 的结点有孩子,因此叶结点数为 2026−1013=10132026-1013=1013。

第 8 题(单选题,2 分)

一棵二叉树的前序遍历为 `A B D E C F G`,中序遍历为 `D B E A F C G`,则其后序遍历为( )。

A.
`D E B F G C A`
B.
`D E B G F C A`
C.
`D B E F C G A`
D.
`E D B F G C A`

正确答案A

解析详情
答案 A二叉树遍历还原
思路与推导
  1. 前序首元素确定根为 A,中序将左右子树划分为 `D B E` 和 `F C G`;分别还原后,后序为 `D E B F G C A`。

第 9 题(单选题,2 分)

元素 `1,2,3,4,5` 按此顺序依次入栈,入栈和出栈操作可以交错进行。下列不可能得到的出栈序列是( )。

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

正确答案C

解析详情
答案 C栈的出栈序列
思路与推导
  1. 要先输出 3,栈中必然已有 `1,2,3`;弹出 3 后栈顶是 2,不可能越过 2 先输出 1,因此 `3,1,2,5,4` 不合法。

第 10 题(单选题,2 分)

下面哪一个序列可以作为一个有 5 个顶点的简单无向连通图的度数序列?( )

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

正确答案B

解析详情
答案 B无向图度数序列
思路与推导
  1. (3,3,2,2,2)(3,3,2,2,2) 可由一个 5 阶环再增加一条弦得到,且图保持连通;其余选项度数和为奇数或含孤立点。

第 11 题(单选题,2 分)

在下列排序算法的常见实现中,通常不具有稳定性的是( )。

A.
插入排序
B.
归并排序
C.
冒泡排序
D.
选择排序

正确答案D

解析详情
答案 D排序稳定性
思路与推导
  1. 选择排序交换最小元素与当前位置时,可能跨过相等元素并改变其相对次序,因此常见实现不稳定。

第 12 题(单选题,2 分)

长度为 8 的二进制串中,不包含两个连续的 `1` 的串共有( )个。

A.
55
B.
54
C.
34
D.
89

正确答案A

解析详情
答案 A递推计数
思路与推导
  1. 设长度为 kk 的合法串数为 fkf_k。末位为 0 时有 fk−1f_{k-1} 种,末位为 1 时前一位必须为 0,有 fk−2f_{k-2} 种;由 f1=2,f2=3f_1=2,f_2=3 得 f8=55f_8=55。

第 13 题(单选题,2 分)

函数 `f` 定义如下,则 `f(5)` 的返回值是( )。

int f(int n) {
    if (n <= 1) return n + 1;
    return f(n - 1) + f(n - 2);
}
A.
13
B.
8
C.
12
D.
21

正确答案A

解析详情
答案 A递归函数求值
思路与推导
  1. 由边界得到 f(0)=1,f(1)=2f(0)=1,f(1)=2,之后依次为 3、5、8、13,所以 `f(5)` 返回 13。

第 14 题(单选题,2 分)

数组 `a[1..n]` 的前缀和定义为 p[0]=0p[0]=0,p[i]=a[1]+a[2]+⋯+a[i]p[i]=a[1]+a[2]+\cdots+a[i]。区间 a[l]+a[l+1]+⋯+a[r]a[l]+a[l+1]+\cdots+a[r] 等于( )。

A.
p[r]−p[l]p[r]-p[l]
B.
p[r]−p[l−1]p[r]-p[l-1]
C.
p[r−1]−p[l]p[r-1]-p[l]
D.
p[r−1]−p[l−1]p[r-1]-p[l-1]

正确答案B

解析详情
答案 B前缀和
思路与推导
  1. `p[r]` 包含前 rr 项,减去前 l−1l-1 项后,恰好留下下标 ll 到 rr 的元素和。

第 15 题(单选题,2 分)

设 nn 为正的 2 的整数次幂,且下列程序不会发生整数溢出。其时间复杂度为( )。

long long cnt = 0;
for (int i = 1; i <= n; i *= 2)
    for (int j = 0; j < i; ++j)
        ++cnt;
A.
O(log⁡n)O(\log n)
B.
O(nlog⁡n)O(n\log n)
C.
O(n)O(n)
D.
O(n2)O(n^2)

正确答案C

解析详情
答案 C复杂度与等比级数
思路与推导
  1. 内层执行次数依次为 1,2,4,ldots,n1,2,4,ldots,n,总次数小于 2n2n,因此时间复杂度为 O(n)O(n)。

二、阅读程序(1)

假设输入字符串只包含小写英文字母,且长度为 nn。判断题正确填 ✓,错误填 ✗。

 1 | #include <iostream>
 2 | #include <string>
 3 | using namespace std;
 4 | string reduce_string(const string &s) {
 5 |     string t;
 6 |     for (char c : s) {
 7 |         if (!t.empty() && t.back() == c)
 8 |             t.pop_back();
 9 |         else
10 |             t.push_back(c);
11 |     }
12 |     return t;
13 | }
14 | int main() {
15 |     string s;
16 |     cin >> s;
17 |     string t = reduce_string(s);
18 |     cout << t << '\n';
19 |     cout << t.size() << '\n';
20 | }

第 16 题(判断题,1 分)

输出字符串长度的奇偶性一定与输入字符串长度的奇偶性相同。

正确答案正确

解析详情
答案 正确奇偶性不变量
思路与推导
  1. 每读入一个字符,`t` 的长度只会增加 1 或减少 1,因此奇偶性每次翻转;处理 nn 个字符后长度与 nn 同奇偶。

第 17 题(判断题,1 分)

若输入为 `abca`,则第一行输出为空行。

正确答案错误

解析详情
答案 错误字符串栈模拟
思路与推导
  1. 输入 `abca` 时相邻字符始终不同,四个字符都会依次压入 `t`,第一行输出 `abca`。

第 18 题(判断题,2 分)

函数返回的字符串中一定不存在两个相邻且相同的字符。

正确答案正确

解析详情
答案 正确栈不变量
思路与推导
  1. 压入字符前要求它与当前末尾不同;弹出只会删除末尾。因此处理过程中以及最终结果中都不会出现相邻相同字符。

第 19 题(判断题,2 分)

若将第 8 行的 `t.pop_back()` 改为 `t.clear()`,程序对任意输入的输出都不变。

正确答案错误

解析详情
答案 错误程序修改与反例
思路与推导
  1. 输入 `abbc` 时原程序得到 `ac`;若改为 `clear()`,处理两个 `b` 后会清空整个 `t`,最终得到 `c`,输出发生变化。

第 20 题(单选题,3 分)

若输入为 `abbaca`,则第一行输出为( )。

A.
空行
B.
`ca`
C.
`aca`
D.
`abaca`

正确答案B

解析详情
答案 B程序输出模拟
思路与推导
  1. 依次处理 `abbaca`:两个 `b` 抵消,随后两个 `a` 抵消,剩余字符依次为 `c`、`a`,第一行输出 `ca`。

第 21 题(单选题,3 分)

该程序的时间复杂度和额外空间复杂度分别为( )。

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

正确答案D

解析详情
答案 D摊还复杂度
思路与推导
  1. 每个输入字符只进行一次判断和一次压入或弹出,时间为 O(n)O(n);最坏情况下 `t` 保存全部字符,额外空间为 O(n)O(n)。

二、阅读程序(2)

输入保证 n≥1n\ge1、k≥1k\ge1,并且数组中的所有元素均为正整数。判断题正确填 ✓,错误填 ✗。

 1 | #include <iostream>
 2 | #include <vector>
 3 | using namespace std;
 4 | int main() {
 5 |     int n;
 6 |     long long k;
 7 |     cin >> n >> k;
 8 |     vector<long long> a(n);
 9 |     for (int i = 0; i < n; ++i) cin >> a[i];
10 |     long long ans = 0, sum = 0;
11 |     int left = 0;
12 |     for (int right = 0; right < n; ++right) {
13 |         sum += a[right];
14 |         while (left <= right && sum > k) {
15 |             sum -= a[left];
16 |             ++left;
17 |         }
18 |         ans += right - left + 1;
19 |     }
20 |     cout << ans << '\n';
21 |     return 0;
22 | }

第 22 题(判断题,2 分)

每次执行完第 14~17 行的 `while` 循环后,都有 `sum <= k`。

正确答案正确

解析详情
答案 正确滑动窗口不变量
思路与推导
  1. 数组元素均为正数,窗口和超出 kk 时不断移动左端点;循环停止时窗口为空或其元素和已经不超过 kk。

第 23 题(判断题,2 分)

将第 14 行的 `while` 改为 `if`,程序对所有合法输入的输出都不变。

正确答案错误

解析详情
答案 错误循环条件与反例
思路与推导
  1. 例如 k=3k=3、数组为 `1 1 3`。加入 3 后窗口和为 5,只删除一个 1 仍为 4,必须继续删除,因此不能把 `while` 改成 `if`。

第 24 题(判断题,2 分)

程序输出的是数组中元素和不超过 kk 的连续非空子数组个数。

正确答案正确

解析详情
答案 正确双指针计数
思路与推导
  1. 固定右端点后,`left` 是最靠左的合法起点;以 `right` 结尾的合法非空子数组共有 `right-left+1` 个,累加后得到全部答案。

第 25 题(判断题,2 分)

由于程序中存在两层循环,因此最坏时间复杂度是 O(n2)O(n^2)。

正确答案错误

解析详情
答案 错误双指针复杂度
思路与推导
  1. 虽然 `while` 位于 `for` 内,但 `left` 在整个程序中最多从 0 增加到 nn,两个指针的总移动次数均为 O(n)O(n)。

第 26 题(单选题,3 分)

若输入如下,则程序输出为( )。

5 5
1 2 1 3 2
A.
8
B.
9
C.
10
D.
11

正确答案C

解析详情
答案 C滑动窗口模拟
思路与推导
  1. 五个右端点分别新增 1、2、3、2、2 个合法子数组,累计为 1+2+3+2+2=101+2+3+2+2=10。

第 27 题(单选题,3 分)

对于固定的 nn,程序输出的最大可能值是( )。

A.
n(n+1)2\frac{n(n+1)}{2}
B.
n2n^2
C.
2n2^n
D.
nn

正确答案A

解析详情
答案 A子数组总数
思路与推导
  1. 当 kk 足够大时所有连续非空子数组都合法。长度为 nn 的数组共有 n+(n-1)+cdots+1= rac{n(n+1)}{2} 个连续非空子数组。

二、阅读程序(3)

输入保证 n≥1n\ge1,且 a[1],a[2],…,a[n]a[1],a[2],\ldots,a[n] 均为非负整数。判断题正确填 ✓,错误填 ✗。

 1 | #include <algorithm>
 2 | #include <iostream>
 3 | #include <vector>
 4 | using namespace std;
 5 | int main() {
 6 |     int n;
 7 |     cin >> n;
 8 |     vector<long long> a(n + 1), dp(n + 1, 0);
 9 |     for (int i = 1; i <= n; ++i) cin >> a[i];
10 |     dp[1] = a[1];
11 |     for (int i = 2; i <= n; ++i)
12 |         dp[i] = max(dp[i - 1], dp[i - 2] + a[i]);
13 |     cout << dp[n] << '\n';
14 |     return 0;
15 | }

第 28 题(判断题,2 分)

`dp[i]` 表示从前 ii 个数中选择若干个互不相邻的数时,能够得到的最大元素和。

正确答案正确

解析详情
答案 正确一维动态规划
思路与推导
  1. 最优方案要么不选第 ii 个数,价值为 `dp[i-1]`;要么选它并跳过第 i−1i-1 个数,价值为 `dp[i-2]+a[i]`,两者取最大。

第 29 题(判断题,2 分)

对于任意 1≤i<n1\le i<n,都有 `dp[i] <= dp[i + 1]`。

正确答案正确

解析详情
答案 正确动态规划单调性
思路与推导
  1. 递推式显式取 `max(dp[i-1], ...)`,所以 `dp[i]` 不会小于 `dp[i-1]`。

第 30 题(判断题,2 分)

将第 12 行改为 `dp[i] = dp[i - 2] + a[i]`,程序对所有合法输入的输出都不变。

正确答案错误

解析详情
答案 错误状态转移完整性
思路与推导
  1. 若只保留 `dp[i-2]+a[i]`,就强制选择第 ii 个数。输入 `2` 和 `5 1` 时会把正确答案 5 算成 1。

第 31 题(判断题,2 分)

该程序的时间复杂度为 O(n2)O(n^2)。

正确答案错误

解析详情
答案 错误线性时间复杂度
思路与推导
  1. 程序只有一次读入循环和一次从 2 到 nn 的递推循环,每轮为常数操作,因此时间复杂度是 O(n)O(n)。

第 32 题(单选题,3 分)

若输入如下,则程序输出为( )。

6
4 2 7 3 6 1
A.
13
B.
14
C.
16
D.
17

正确答案D

解析详情
答案 D动态规划模拟
思路与推导
  1. `dp[1..6]` 依次为 `4,4,11,11,17,17`,对应可选择 4、7、6,最大和为 17。

第 33 题(单选题,3 分)

若所有 a[i]a[i] 都等于 1,则程序输出为( )。

A.
⌊n2⌋\left\lfloor\frac{n}{2}\right\rfloor
B.
⌈n2⌉\left\lceil\frac{n}{2}\right\rceil
C.
n−1n-1
D.
nn

正确答案B

解析详情
答案 B不相邻选择计数
思路与推导
  1. 所有权值都是 1 时,只需选择尽可能多的不相邻位置,最多可取第 1、3、5……个位置,共 lceiln/2ceillceil n/2 ceil 个。

三、完善程序(1)迷宫最短路

给定一个 n×mn\times m 的迷宫,字符 `.` 表示可以通过,字符 `#` 表示障碍。起点和终点坐标均从 0 开始编号,且保证起点、终点不是障碍。每次可以向上、下、左、右移动一格。程序输出从起点到终点的最少移动次数;若无法到达则输出 `-1`。

 1 | #include <iostream>
 2 | #include <queue>
 3 | #include <string>
 4 | #include <utility>
 5 | #include <vector>
 6 | using namespace std;
 7 | int main() {
 8 |     int n, m, sx, sy, tx, ty;
 9 |     cin >> n >> m;
10 |     vector<string> g(n);
11 |     for (int i = 0; i < n; ++i) cin >> g[i];
12 |     cin >> sx >> sy >> tx >> ty;
13 |     vector<vector<int>> dist(n, vector<int>(m, -1));
14 |     queue<pair<int, int>> q;
15 |     ① = 0;
16 |     q.push(②);
17 |     int dx[4] = {-1, 1, 0, 0};
18 |     int dy[4] = {0, 0, -1, 1};
19 |     while (!q.empty()) {
20 |         pair<int, int> cur = q.front();
21 |         int x = cur.first, y = cur.second;
22 |         ③;
23 |         for (int d = 0; d < 4; ++d) {
24 |             int nx = x + dx[d], ny = y + dy[d];
25 |             if (nx < 0 || nx >= n || ny < 0 || ny >= m) continue;
26 |             if (④) {
27 |                 dist[nx][ny] = ⑤;
28 |                 q.push(make_pair(nx, ny));
29 |             }
30 |         }
31 |     }
32 |     cout << dist[tx][ty] << '\n';
33 |     return 0;
34 | }

第 34 题(单选题,3 分)

① 处应填( )。

A.
dist[tx][ty]
B.
dist[0][0]
C.
dist[sx][sy]
D.
dist[sy][sx]

正确答案C

解析详情
答案 CBFS 起点初始化
思路与推导
  1. 最短路从起点开始,起点到自身的距离为 0,因此应设置 `dist[sx][sy] = 0`。

第 35 题(单选题,3 分)

② 处应填( )。

A.
make_pair(sx, sy)
B.
make_pair(tx, ty)
C.
make_pair(0, 0)
D.
make_pair(sy, sx)

正确答案A

解析详情
答案 ABFS 队列初始化
思路与推导
  1. 队列中首先应放入起点坐标 `make_pair(sx, sy)`,搜索才能从起点向四周扩展。

第 36 题(单选题,3 分)

③ 处应填( )。

A.
q.push(cur)
B.
q.front()
C.
q.back()
D.
q.pop()

正确答案D

解析详情
答案 D队列操作
思路与推导
  1. 读取 `q.front()` 后必须执行 `q.pop()` 删除当前结点,否则它会被反复处理,循环无法正常推进。

第 37 题(单选题,3 分)

④ 处应填( )。

A.
g[nx][ny] == '#' && dist[nx][ny] == -1
B.
g[nx][ny] != '#' && dist[nx][ny] == -1
C.
g[nx][ny] != '#' && dist[nx][ny] != -1
D.
g[nx][ny] == '#' || dist[nx][ny] == -1

正确答案B

解析详情
答案 BBFS 可达条件
思路与推导
  1. 相邻格既要不是障碍 `#`,又要尚未访问,即 `dist[nx][ny] == -1`,满足两者时才能入队。

第 38 题(单选题,3 分)

⑤ 处应填( )。

A.
dist[nx][ny] + 1
B.
dist[sx][sy] + 1
C.
dist[x][y] + 1
D.
dist[x][y] - 1

正确答案C

解析详情
答案 CBFS 距离转移
思路与推导
  1. 从当前格移动一步到相邻格,因此新格距离应为 `dist[x][y] + 1`。

三、完善程序(2)区间素数计数

给定 nn 和 qq,其中 2≤n≤1062\le n\le10^6。程序先预处理不超过 nn 的所有素数,然后回答 qq 次询问。每次给出 1≤l≤r≤n1\le l\le r\le n,输出区间 [l,r][l,r] 内素数的个数。

 1 | #include <iostream>
 2 | #include <vector>
 3 | using namespace std;
 4 | int main() {
 5 |     int n, q;
 6 |     cin >> n >> q;
 7 |     vector<bool> is_prime(n + 1, true);
 8 |     is_prime[0] = is_prime[1] = false;
 9 |     for (int i = 2; ①; ++i)
10 |         if (is_prime[i])
11 |             for (int j = ②; j <= n; j += i)
12 |                 is_prime[j] = ③;
13 |     vector<int> pre(n + 1, 0);
14 |     for (int i = 1; i <= n; ++i)
15 |         pre[i] = ④;
16 |     while (q--) {
17 |         int l, r;
18 |         cin >> l >> r;
19 |         cout << ⑤ << '\n';
20 |     }
21 |     return 0;
22 | }

第 39 题(单选题,3 分)

① 处应填( )。

A.
i * i <= n
B.
i <= n
C.
i < n / 2
D.
i * 2 <= n

正确答案A

解析详情
答案 A埃氏筛枚举上界
思路与推导
  1. 每个合数至少有一个不超过其平方根的质因数,所以只需枚举到 `i * i <= n`。

第 40 题(单选题,3 分)

② 处应填( )。

A.
2 * i
B.
i + 1
C.
i * i
D.
n / i

正确答案C

解析详情
答案 C埃氏筛起点
思路与推导
  1. 当处理质数 ii 时,小于 i2i^2 的倍数已经被更小的质因数筛过,因此从 `i * i` 开始即可。

第 41 题(单选题,3 分)

③ 处应填( )。

A.
true
B.
false
C.
j
D.
i

正确答案B

解析详情
答案 B素数筛标记
思路与推导
  1. `j` 是质数 ii 的倍数且不小于 i2i^2,一定是合数,所以应令 `is_prime[j] = false`。

第 42 题(单选题,3 分)

④ 处应填( )。

A.
pre[i] + is_prime[i]
B.
pre[i - 1] + i
C.
pre[i - 1] + is_prime[i - 1]
D.
pre[i - 1] + (is_prime[i] ? 1 : 0)

正确答案D

解析详情
答案 D素数前缀和
思路与推导
  1. `pre[i]` 应等于前 i−1i-1 个数中的素数个数,再加上 ii 自身是否为素数,即 `pre[i-1] + (is_prime[i] ? 1 : 0)`。

第 43 题(单选题,3 分)

⑤ 处应填( )。

A.
pre[r] - pre[l - 1]
B.
pre[r] - pre[l]
C.
pre[r - 1] - pre[l - 1]
D.
pre[r] + pre[l - 1]

正确答案A

解析详情
答案 A区间计数
思路与推导
  1. `pre[r]` 统计 1 到 rr 的素数个数,减去 1 到 l−1l-1 的个数后,得到闭区间 [l,r][l,r] 的答案。