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

解析详情

【答案】B

【考点】g++ 编译命令

【解析】 `-o app` 指定输出文件名为 `app`;编译成功后生成该可执行文件,但不会自动运行。

【易错点】 不要把输出文件名误认为源文件扩展名。

2 题(单选题2 分)

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

A.
128127-128\sim127
B.
01270\sim127
C.
255255-255\sim255
D.
02550\sim255

正确答案D

解析详情

【答案】D

【考点】无符号整数范围

【解析】 8 位无符号整数共有 282^8 种状态,因此取值为 00281=2552^8-1=255

【易错点】 无符号类型没有符号位,最小值是 0。

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

【考点】引用传参与值传参

【解析】 `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

解析详情

【答案】C

【考点】string 修改操作

【解析】 `erase(1, 2)` 删除下标 1 开始的 `sp`,得到 `cj`;再在下标 1 插入 `++`,得到 `c++j`。

【易错点】 `erase` 的第二个参数是删除字符数,不是结束下标。

5 题(单选题2 分)

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

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

正确答案D

解析详情

【答案】D

【考点】按位异或

【解析】 `1 << 3` 等于 8,42 的第 3 位为 1;与 8 异或会把该位翻转为 0,所以结果为 428=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

【考点】进制转换

【解析】 (101101)2=45(101101)_2=45(27)8=23(27)_8=23,两者之和为 68,即十六进制的 (44)16(44)_{16}

【易错点】 八进制的 27 不是十进制的 27。

7 题(单选题2 分)

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

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

正确答案B

解析详情

【答案】B

【考点】完全二叉树

【解析】 顺序编号为 1 到 2026 时,编号不超过 lfloor2026/2floor=1013lfloor2026/2 floor=1013 的结点有孩子,因此叶结点数为 20261013=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

【考点】二叉树遍历还原

【解析】 前序首元素确定根为 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

【考点】栈的出栈序列

【解析】 要先输出 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

【考点】无向图度数序列

【解析】 (3,3,2,2,2)(3,3,2,2,2) 可由一个 5 阶环再增加一条弦得到,且图保持连通;其余选项度数和为奇数或含孤立点。

【易错点】 度数和为偶数只是必要条件,还需满足可实现性与连通性。

11 题(单选题2 分)

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

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

正确答案D

解析详情

【答案】D

【考点】排序稳定性

【解析】 选择排序交换最小元素与当前位置时,可能跨过相等元素并改变其相对次序,因此常见实现不稳定。

【易错点】 归并排序只有在相等时优先取左段元素才保持稳定。

12 题(单选题2 分)

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

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

正确答案A

解析详情

【答案】A

【考点】递推计数

【解析】 设长度为 kk 的合法串数为 fkf_k。末位为 0 时有 fk1f_{k-1} 种,末位为 1 时前一位必须为 0,有 fk2f_{k-2} 种;由 f1=2,f2=3f_1=2,f_2=3f8=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

【考点】递归函数求值

【解析】 由边界得到 f(0)=1,f(1)=2f(0)=1,f(1)=2,之后依次为 3、5、8、13,所以 `f(5)` 返回 13。

【易错点】 边界值不是常见斐波那契数列的 0 和 1。

14 题(单选题2 分)

数组 `a[1..n]` 的前缀和定义为 p[0]=0p[0]=0p[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[l1]p[r]-p[l-1]
C.
p[r1]p[l]p[r-1]-p[l]
D.
p[r1]p[l1]p[r-1]-p[l-1]

正确答案B

解析详情

【答案】B

【考点】前缀和

【解析】 `p[r]` 包含前 rr 项,减去前 l1l-1 项后,恰好留下下标 llrr 的元素和。

【易错点】 左端点为 ll 时应减 `p[l-1]`。

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(logn)O(\log n)
B.
O(nlogn)O(n\log n)
C.
O(n)O(n)
D.
O(n2)O(n^2)

正确答案C

解析详情

【答案】C

【考点】复杂度与等比级数

【解析】 内层执行次数依次为 1,2,4,ldots,n1,2,4,ldots,n,总次数小于 2n2n,因此时间复杂度为 O(n)O(n)

【易错点】 外层是对数级,不代表总复杂度一定要再乘 nn

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

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

正确答案正确

解析详情

【答案】正确

【考点】奇偶性不变量

【解析】 每读入一个字符,`t` 的长度只会增加 1 或减少 1,因此奇偶性每次翻转;处理 nn 个字符后长度与 nn 同奇偶。

【易错点】 消除两个相同字符是逐字符处理产生的净效果。

17 题(判断题1 分)

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

正确答案错误

解析详情

【答案】错误

【考点】字符串栈模拟

【解析】 输入 `abca` 时相邻字符始终不同,四个字符都会依次压入 `t`,第一行输出 `abca`。

【易错点】 程序只消除处理时相邻的相同字符。

18 题(判断题2 分)

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

正确答案正确

解析详情

【答案】正确

【考点】栈不变量

【解析】 压入字符前要求它与当前末尾不同;弹出只会删除末尾。因此处理过程中以及最终结果中都不会出现相邻相同字符。

【易错点】 不能只检查原字符串中是否存在相邻重复。

19 题(判断题2 分)

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

正确答案错误

解析详情

【答案】错误

【考点】程序修改与反例

【解析】 输入 `abbc` 时原程序得到 `ac`;若改为 `clear()`,处理两个 `b` 后会清空整个 `t`,最终得到 `c`,输出发生变化。

【易错点】 `pop_back()` 只删除一个字符,`clear()` 会删除全部字符。

20 题(单选题3 分)

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

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

正确答案B

解析详情

【答案】B

【考点】程序输出模拟

【解析】 依次处理 `abbaca`:两个 `b` 抵消,随后两个 `a` 抵消,剩余字符依次为 `c`、`a`,第一行输出 `ca`。

【易错点】 每次消除后要继续使用新的栈顶判断后续字符。

21 题(单选题3 分)

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

A.
O(1)O(1)O(1)O(1)
B.
O(nlogn)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

【考点】摊还复杂度

【解析】 每个输入字符只进行一次判断和一次压入或弹出,时间为 O(n)O(n);最坏情况下 `t` 保存全部字符,额外空间为 O(n)O(n)

【易错点】 字符串尾部压入、弹出的摊还代价为常数。

二、阅读程序(2)

输入保证 n1n\ge1k1k\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`。

正确答案正确

解析详情

【答案】正确

【考点】滑动窗口不变量

【解析】 数组元素均为正数,窗口和超出 kk 时不断移动左端点;循环停止时窗口为空或其元素和已经不超过 kk

【易错点】 结论依赖所有数组元素为正。

23 题(判断题2 分)

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

正确答案错误

解析详情

【答案】错误

【考点】循环条件与反例

【解析】 例如 k=3k=3、数组为 `1 1 3`。加入 3 后窗口和为 5,只删除一个 1 仍为 4,必须继续删除,因此不能把 `while` 改成 `if`。

【易错点】 一次缩短窗口未必足以恢复合法状态。

24 题(判断题2 分)

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

正确答案正确

解析详情

【答案】正确

【考点】双指针计数

【解析】 固定右端点后,`left` 是最靠左的合法起点;以 `right` 结尾的合法非空子数组共有 `right-left+1` 个,累加后得到全部答案。

【易错点】 题目统计的是连续子数组,不是任意子序列。

25 题(判断题2 分)

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

正确答案错误

解析详情

【答案】错误

【考点】双指针复杂度

【解析】 虽然 `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、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

【考点】子数组总数

【解析】 当 kk 足够大时所有连续非空子数组都合法。长度为 nn 的数组共有 n+(n-1)+cdots+1= rac{n(n+1)}{2} 个连续非空子数组。

【易错点】 连续子数组的数量不是 2n2^n

二、阅读程序(3)

输入保证 n1n\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 个数中选择若干个互不相邻的数时,能够得到的最大元素和。

正确答案正确

解析详情

【答案】正确

【考点】一维动态规划

【解析】 最优方案要么不选第 ii 个数,价值为 `dp[i-1]`;要么选它并跳过第 i1i-1 个数,价值为 `dp[i-2]+a[i]`,两者取最大。

【易错点】 状态描述的是前缀范围内的最优值,不要求必须选择第 ii 个数。

29 题(判断题2 分)

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

正确答案正确

解析详情

【答案】正确

【考点】动态规划单调性

【解析】 递推式显式取 `max(dp[i-1], ...)`,所以 `dp[i]` 不会小于 `dp[i-1]`。

【易错点】 单个数组元素大小可以下降,但前缀最优值不会下降。

30 题(判断题2 分)

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

正确答案错误

解析详情

【答案】错误

【考点】状态转移完整性

【解析】 若只保留 `dp[i-2]+a[i]`,就强制选择第 ii 个数。输入 `2` 和 `5 1` 时会把正确答案 5 算成 1。

【易错点】 最优转移必须同时考虑选与不选。

31 题(判断题2 分)

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

正确答案错误

解析详情

【答案】错误

【考点】线性时间复杂度

【解析】 程序只有一次读入循环和一次从 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

【考点】动态规划模拟

【解析】 `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.
n1n-1
D.
nn

正确答案B

解析详情

【答案】B

【考点】不相邻选择计数

【解析】 所有权值都是 1 时,只需选择尽可能多的不相邻位置,最多可取第 1、3、5……个位置,共 lceiln/2ceillceil n/2 ceil 个。

【易错点】 当 nn 为奇数时答案比 lfloorn/2floorlfloor n/2 floor 多 1。

三、完善程序(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

解析详情

【答案】C

【考点】BFS 起点初始化

【解析】 最短路从起点开始,起点到自身的距离为 0,因此应设置 `dist[sx][sy] = 0`。

【易错点】 目标点距离应由搜索过程得到,不能预先设为 0。

35 题(单选题3 分)

② 处应填( )。

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

正确答案A

解析详情

【答案】A

【考点】BFS 队列初始化

【解析】 队列中首先应放入起点坐标 `make_pair(sx, sy)`,搜索才能从起点向四周扩展。

【易错点】 终点只用于读取最终距离。

36 题(单选题3 分)

③ 处应填( )。

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

正确答案D

解析详情

【答案】D

【考点】队列操作

【解析】 读取 `q.front()` 后必须执行 `q.pop()` 删除当前结点,否则它会被反复处理,循环无法正常推进。

【易错点】 `front()` 只读取队首,不会自动出队。

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

解析详情

【答案】B

【考点】BFS 可达条件

【解析】 相邻格既要不是障碍 `#`,又要尚未访问,即 `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

解析详情

【答案】C

【考点】BFS 距离转移

【解析】 从当前格移动一步到相邻格,因此新格距离应为 `dist[x][y] + 1`。

【易错点】 新格原来的距离为 -1,不能在它的旧值上加 1。

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

给定 nnqq,其中 2n1062\le n\le10^6。程序先预处理不超过 nn 的所有素数,然后回答 qq 次询问。每次给出 1lrn1\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

【考点】埃氏筛枚举上界

【解析】 每个合数至少有一个不超过其平方根的质因数,所以只需枚举到 `i * i <= n`。

【易错点】 循环到 nn 虽可能得到结果,但会破坏标准筛法的复杂度设计。

40 题(单选题3 分)

② 处应填( )。

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

正确答案C

解析详情

【答案】C

【考点】埃氏筛起点

【解析】 当处理质数 ii 时,小于 i2i^2 的倍数已经被更小的质因数筛过,因此从 `i * i` 开始即可。

【易错点】 从 `2*i` 开始会重复标记大量合数。

41 题(单选题3 分)

③ 处应填( )。

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

正确答案B

解析详情

【答案】B

【考点】素数筛标记

【解析】 `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

【考点】素数前缀和

【解析】 `pre[i]` 应等于前 i1i-1 个数中的素数个数,再加上 ii 自身是否为素数,即 `pre[i-1] + (is_prime[i] ? 1 : 0)`。

【易错点】 前缀状态必须从 `pre[i-1]` 转移。

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

【考点】区间计数

【解析】 `pre[r]` 统计 1 到 rr 的素数个数,减去 1 到 l1l-1 的个数后,得到闭区间 [l,r][l,r] 的答案。

【易错点】 左端点 ll 本身属于查询区间,因此减 `pre[l-1]`。