一、单项选择题
(共 15 题,每题 2 分,共计 30 分;每题有且仅有一个正确选项)
试卷解析 · 理解每一步
CSPJ-2025-R1-Mock-Luogu
试卷解析总览,可直接查看每题答案与解析。
(共 15 题,每题 2 分,共计 30 分;每题有且仅有一个正确选项)
GNU GCC 是常用的 C/C++ 语言编译器。现需要使用 `g++` 将 `luogu.cpp` 编译为可执行文件 `luogu`,可以使用编译命令( )。
g++ -S luogu luogu.cppg++ -S luogu.cpp luogug++ -o luogu luogu.cppg++ -o luogu.cpp luogu正确答案C
`-o luogu` 指定输出文件名为 `luogu`,最后的 `luogu.cpp` 是待编译源文件,因此命令应为 `g++ -o luogu luogu.cpp`。
关于编译语言与解释语言,以下说法错误的是( )。
正确答案B
编译后的可执行文件可以反复运行;只有源代码改变或构建条件变化时才需要重新编译,所以 B 错误。
阅读下面的代码,若输入的 `x` 是 1 至 10 范围内的正整数,输出不可能是( )。
#include <iostream>
using namespace std;
int main() {
int x;
cin >> x;
switch (x) {
case 1: { cout << "A"; break; }
case 3: { cout << "C"; }
default: { cout << "Q"; }
case 5: { cout << "E"; }
}
return 0;
}正确答案D
输入 1 输出 `A`;输入 3 从 `case 3` 贯穿得到 `CQE`;其他未匹配值从 `default` 贯穿得到 `QE`,输入 5 则输出 `E`。单独的 `Q` 不会出现。
()进制数 与十进制数( )相等。
正确答案C
进制的 按位权展开为 。
阅读以下代码片段。当代码片段执行完毕后,`ans` 的值为( )。
int N = 10, ans = 0, x = 0;
for (int i = 1; i <= N; i++) {
for (int j = i + 1; j <= N; j++) {
ans += ++x;
}
}正确答案D
内层循环共执行 次,`x` 依次取 1 到 45,故 `ans=1+2+\cdots+45=1035`。
给定一个空栈,支持入栈和出栈操作。将 1 至 10 依次入栈,第一个出栈的数为 8,则第二个出栈的数不可能为( )。
正确答案A
首次弹出 8 后,栈顶是 7;此后可以直接弹出 7,也可以先压入并弹出 9 或 10,但不可能越过 7 到 2 而让 1 第二个出栈。
有序表中有 100 个元素,使用二分法查找元素 X。有( )个数可以通过恰好 5 次查找找到。
正确答案D
二分查找的比较过程形成二叉判定树,第 5 层有 个位置,因此恰好比较 5 次找到的元素有 16 个。
下面的表格是无向图 G 的邻接矩阵,图 G 中度最大的点的度为( )。
A B C D E
A 0 1 1 0 1
B 1 0 1 0 0
C 1 1 0 1 1
D 0 0 1 0 1
E 1 0 1 1 0正确答案D
无向图中顶点的度等于邻接矩阵对应行中 1 的个数;C 行有 4 个 1,为最大值。
8 支队伍均分为第一组与第二组进行小组赛。A 队和 B 队在同一组,而与 C 队不在同一组的分组方案数有( )种。
正确答案B
第一、第二组有标签。A、B 可同在任一组,再从除 C 外的 5 支队伍中选 2 支同组,方案数为 。
将一根长度为 3 的木棍折为三段,当断点的位置在木棍中等概率分布时,三段木棍可以构成三角形的概率为( )。
正确答案C
两个断点把长度归一化后,三段能成三角形等价于最长一段小于 ;在两个断点的单位正方形样本空间中,满足条件区域面积占 。
下列关于快速排序的说法中,不正确的是( )。
正确答案B
快速排序在划分极不均衡时会退化为 ,最坏时间复杂度是 ,因此 B 不正确。
关于整数的各种 8 位二进制编码方法,说法错误的是( )。
正确答案D
-17 的原码是 `10010001`,22 的补码是 `00010110`,-13 的反码是 `11110010`,A、B、C 均正确,所以“以上说法存在错误”本身错误。
表达式 中, 的系数为( )。
正确答案C
取两次 时幂次为 ,其系数为 。
二叉树 T 的中序遍历为 `CGEADBF`,后序遍历为 `GECDFBA`,则其前序遍历为( )。
正确答案A
后序末尾确定根为 A;由中序划分可还原左子树前序为 `CEG`、右子树前序为 `BDF`,所以整树前序为 `ACEGBDF`。
2024 年,来自谷歌 DeepMind 的米斯·哈萨比斯和约翰·江珀获得了( ),以表彰他们在人工智能方面的贡献。
正确答案C
米斯·哈萨比斯和约翰·江珀获得了 2024 年诺贝尔化学奖,因此选择“诺贝尔奖”。
1 | #include <bits/stdc++.h>
2 | using namespace std;
3 |
4 | int main() {
5 | int l, r;
6 | cin >> l >> r;
7 | int cnt = 0;
8 | long long sum = 0;
9 | for (int i = l; i <= r; ++i) {
10 | if ((i & (i - 1)) != 0) {
11 | cnt += 1;
12 | sum += i;
13 | }
14 | }
15 | cout << cnt << " " << sum << endl;
16 | return 0;
17 | }假设输入的 `l` 和 `r` 均为不超过 的正整数,且满足 ,完成下面的判断题和单选题。
当输入为 `2 5` 时,程序的输出为 `2 8`。( )
正确答案正确
条件 `(i & (i - 1)) != 0` 选中非 2 的幂。区间 2~5 中只有 3、5 被计入,数量为 2、和为 8。
程序的输出总是两个正整数。( )
正确答案错误
若区间只包含一个 2 的幂,例如输入 `1 1`,没有元素被计入,程序输出 `0 0`,并非两个正整数。
将第 8 行的 `long long` 改为 `int`,程序行为不变。( )
正确答案错误
当区间较大时,被累加元素的和可接近 ,超过 32 位 `int` 上限;改成 `int` 会发生溢出,程序行为会改变。
当输入为 `1 100` 时,程序的输出为( )。
正确答案A
1~100 共 100 个数,其中 2 的幂有 1、2、4、8、16、32、64 共 7 个;故 `cnt=93`,`sum=5050-127=4923`。
当输入为 `10000 1000000` 时,程序的第一个输出为( )。
正确答案C
区间共有 个数,其中 2 的幂为 到 共 6 个,因此首个输出为 。
1 | #include <bits/stdc++.h>
2 | using namespace std;
3 |
4 | int main() {
5 | int n, m;
6 | cin >> n >> m;
7 | vector<int> a(n);
8 | for (int i = 0; i < n; ++i) {
9 | cin >> a[i];
10 | }
11 | vector<int> dp(m + 1);
12 | dp[0] = 0;
13 | for (int i = 1; i <= m; ++i) {
14 | int now = 0;
15 | for (int j = 0; j < n; ++j) {
16 | if (i >= a[j] && dp[i - a[j]] == 0) {
17 | now = a[j];
18 | }
19 | }
20 | dp[i] = now;
21 | }
22 | cout << dp[m] << endl;
23 | return 0;
24 | }假设输入的 `n` 和 `m` 均为不超过 1000 的正整数,输入的 `a[i]` 均为不超过 `m` 的正整数,完成下面的判断题和单选题。
当输入为 `3 5 1 3 4` 时,程序的输出为 0。( )
正确答案错误
依次计算得到 `dp[0..5] = 0,1,0,3,4,3`,所以最终输出 `dp[5]=3`,不是 0。
当输入的数组 `a` 为 `{1}` 且 `m` 为偶数时,程序的输出为 0。( )
正确答案正确
当 `a={1}` 时,`dp[i]` 只依赖 `dp[i-1]`:奇数位置为 1,偶数位置为 0,因此偶数 `m` 输出 0。
将第 16 行的条件 `i >= a[j] && dp[i - a[j]] == 0` 改为 `dp[i - a[j]] == 0`,程序可能会产生编译错误。( )
正确答案错误
删除 `i >= a[j]` 后,`i<a[j]` 时会访问负下标;代码仍可通过编译,但运行时发生越界和未定义行为,因此不是编译错误。
当输入为 `4 13 1 2 3 4` 时,程序的输出为( )。
正确答案D
可选步长为 1~4 时,输态是 5 的倍数;,最后一个能从输态 10 转移来的步长为 3,所以输出 3。
当输入为 `7 1000 1 2 3 4 5 6 7` 时,程序的输出为( )。
正确答案A
步长为 1~7 时,输态是 8 的倍数。1000 能被 8 整除,因此 `dp[1000]=0`。
当输入的数组 `a` 为 `{1,2,3,4,5}` 时,有( )个符合数据范围的整数 `m` 使得输出为 3。
正确答案B
步长为 1~5 时,输出 3 恰在 。又因数组元素 5 必须不超过 `m`,需排除 ;从 9 到 999 共 个。
1 | #include <bits/stdc++.h>
2 | using namespace std;
3 |
4 | vector<int> primes;
5 | int comp_by[2000005];
6 | void sieve(int n) {
7 | for (int x = 2; x <= n; x++) {
8 | if (comp_by[x] == 0)
9 | primes.push_back(x);
10 | for (int i = 0; i < primes.size(); i++) {
11 |
12 | if (x * primes[i] > n) break;
13 | comp_by[x * primes[i]] = primes[i];
14 | if (x % primes[i] == 0) break;
15 | }
16 | }
17 | }
18 | int main() {
19 | freopen("input.txt", "w", stdout);
20 | freopen("output.txt", "r", stdin);
21 | int n;
22 | cin >> n;
23 | sieve(n);
24 | for (int i = 1; i <= n; i++)
25 | cout << comp_by[i] << ' ';
26 | return 0;
27 | }假设输入的 `n` 是不超过 的正整数,完成下面的判断题和选择题。
提示:伯特兰-切比雪夫定理:对任意 ,存在质数 使得 。
程序将从 `input.txt` 读入数据,输出到 `output.txt`。( )
正确答案错误
第一条把标准输出以写模式重定向到 `input.txt`,第二条把标准输入以读模式重定向到 `output.txt`,方向与题目描述正好相反。
交换程序的第 12 行和第 13 行,不会导致数组越界。( )
正确答案正确
交换后会先写 `comp_by[x*primes[i]]` 再判断是否大于 `n`;首次越过 `n` 时乘数至多为 2,故下标不超过 ,仍小于数组长度 2000005。
对于所有正整数 `i`,满足 ,输出的第 `i` 个数是 0 当且仅当 `i` 是质数。( )
正确答案错误
筛法中质数位置保持 0,但 `comp_by[1]` 也为 0,而 1 不是质数,所以“当且仅当”不成立。
该程序的主要流程最接近( )。
正确答案D
程序按质数表枚举并在遇到 `x` 的最小质因子时停止,使每个合数按其最小质因子生成一次,属于欧拉筛。
将程序的第 14 行移动到第 11 行,当输入为 1000000 时,输出的第( )个数会发生改变。
正确答案B
把整除判断移到赋值之前后,`x=15` 遇到质数 3 会先退出,45 不再被标记,故第 45 个输出改变;75、105 仍可由更早的乘积标记,97 本来就是质数。
当输入为 100 时,输出的所有数字之和为( )。
正确答案C
`comp_by` 保存合数的最小质因子。100 以内贡献分别为:偶合数 ,最小质因子为 3、5、7 的奇合数贡献 48、30、21,总和为 197。
(全排列检查)给定长度为 `n` 的数组 `a`,判断其是否构成全排列。如果 都恰好在数组 `a` 中出现且仅出现一次,那么就称这个数组是一个全排列。
试补全程序。
#include <bits/stdc++.h>
using namespace std;
bool is_permutation(vector<int> &a) {
int n = /* ① */;
vector<int> count(/* ② */);
for (int i = 0; i < n; i++) {
if (/* ③ */)
count[a[i]]++;
else
/* ④ */;
}
for (int i = 1; i <= n; i++)
if (count[/* ⑤ */] > 1)
return false;
return true;
}
int main() {
int n;
cin >> n;
vector<int> a(n);
for (int i = 0; i < n; i++)
cin >> a[i];
if (is_permutation(a))
cout << "The sequence is a permutation.";
else
cout << "The sequence is not a permutation.";
return 0;
}① 处应填( )。
a.length()a.size()a.back()a.capacity()正确答案B
形参 `a` 是 `vector<int>`,元素个数由 `a.size()` 返回,因此 ① 填 `a.size()`。
② 处应填( )。
0nn + 11000000000正确答案C
程序会访问 `count[1]` 到 `count[n]`,所以需要 `n+1` 个元素,合法下标为 0~n。
③ 处应填( )。
1 <= a[i] && a[i] <= n1 <= a[i] <= n1 <= a[i] || a[i] <= na[i] < 1 || a[i] > n正确答案A
合法值必须同时满足 `1 <= a[i]` 和 `a[i] <= n`,应使用逻辑与连接两个比较。
④ 处应填( )。
breakcontinuereturn truereturn false正确答案D
一旦发现元素不在 1~n 范围内,数组不可能是全排列,应立即 `return false`。
⑤ 处应填( )。
ia[i]i - 1i / 2正确答案A
循环变量 `i` 正在枚举数值 1~n,应检查对应的 `count[i]` 是否大于 1,所以 ⑤ 填 `i`。
(跳跃)给定一个数组 ,每次跳跃从当前位置 `x` 跳至位置 `a[x]`。回答 `q` 次询问,每次给出 `(x,k)`,输出从 `x` 跳跃 `k` 次后的位置编号。
试补全程序。
#include <iostream>
using namespace std;
const int N = 100010, LOG = 20;
int a[N], dp[N][LOG];
int main() {
int n, q;
cin >> n >> q;
for (int i = 0; i < n; i++) cin >> a[i];
for (int i = 0; i < n; i++) {
dp[i][0] = /* ① */;
}
for (int k = 1; k < LOG; k++) {
for (int i = 0; i < n; i++) {
dp[i][k] = /* ② */;
}
}
while (q--) {
int x, k;
cin >> x >> k;
int u = x;
for (int j = 0; j < LOG; j++) {
if (/* ③ */) {
u = /* ④ */;
}
}
cout << /* ⑤ */ << endl;
}
return 0;
}① 处应填( )。
ia[i]0dp[i][1]正确答案B
`dp[i][0]` 表示从位置 `i` 跳 次后的编号,按定义就是 `a[i]`。
② 处应填( )。
dp[dp[i][k - 1]][k - 1]dp[i][k - 1] + dp[i][k - 1]dp[i - 1][k - 1]dp[k - 1][i]正确答案A
跳 次可拆成两段 次,先到 `dp[i][k-1]`,再跳同样次数,因此转移为 `dp[dp[i][k-1]][k-1]`。
③ 处应填( )。
k & jk >> j(k >> j) & 1(k >> j) ^ 1正确答案C
枚举第 `j` 位时,只有 `k` 的该位为 1 才执行对应的 次跳跃,条件应为 `(k >> j) & 1`。
④ 处应填( )。
dp[j][u]dp[k][u]dp[u][j]a[u]正确答案C
当第 `j` 位有效时,当前位置 `u` 应沿预处理表跳 次,更新为 `dp[u][j]`。
⑤ 处应填( )。
uxkdp[u][0]正确答案A
循环结束后 `u` 已经累计完成 `k` 次跳跃,应该直接输出 `u`。