GESP 客观题评测系统

试卷解析 · 理解每一步

2025 洛谷 SCP-J 第一轮模拟题(入门级 C++)

CSPJ-2025-R1-Mock-Luogu

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

一、单项选择题

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

第 1 题(单选题,2 分)

GNU GCC 是常用的 C/C++ 语言编译器。现需要使用 `g++` 将 `luogu.cpp` 编译为可执行文件 `luogu`,可以使用编译命令( )。

A.
g++ -S luogu luogu.cpp
B.
g++ -S luogu.cpp luogu
C.
g++ -o luogu luogu.cpp
D.
g++ -o luogu.cpp luogu

正确答案C

解析详情
答案 CGCC 编译命令
思路与推导
  1. `-o luogu` 指定输出文件名为 `luogu`,最后的 `luogu.cpp` 是待编译源文件,因此命令应为 `g++ -o luogu luogu.cpp`。

第 2 题(单选题,2 分)

关于编译语言与解释语言,以下说法错误的是( )。

A.
C++ 语言是编译语言,需要先经过编译得到可执行程序,才能交由机器执行。
B.
编译语言程序每一次执行都需要重新编译。
C.
解释器负责将解释语言的源程序翻译为可以执行的机器代码。
D.
Python 是常见的解释语言。

正确答案B

解析详情
答案 B编译语言与解释语言
思路与推导
  1. 编译后的可执行文件可以反复运行;只有源代码改变或构建条件变化时才需要重新编译,所以 B 错误。

第 3 题(单选题,2 分)

阅读下面的代码,若输入的 `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;
}
A.
A
B.
CQE
C.
QE
D.
Q

正确答案D

解析详情
答案 Dswitch 贯穿执行
思路与推导
  1. 输入 1 输出 `A`;输入 3 从 `case 3` 贯穿得到 `CQE`;其他未匹配值从 `default` 贯穿得到 `QE`,输入 5 则输出 `E`。单独的 `Q` 不会出现。

第 4 题(单选题,2 分)

kk(k>4k>4)进制数 43214321 与十进制数( )相等。

A.
43214321
B.
4k4+3k3+2k2+k4k^4+3k^3+2k^2+k
C.
4k3+3k2+2k+14k^3+3k^2+2k+1
D.
10k10k

正确答案C

解析详情
答案 C进制展开
思路与推导
  1. kk 进制的 43214321 按位权展开为 4k3+3k2+2k+14k^3+3k^2+2k+1。

第 5 题(单选题,2 分)

阅读以下代码片段。当代码片段执行完毕后,`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;
    }
}
A.
45
B.
55
C.
990
D.
1035

正确答案D

解析详情
答案 D循环计数与等差数列
思路与推导
  1. 内层循环共执行 9+8+⋯+1=459+8+\cdots+1=45 次,`x` 依次取 1 到 45,故 `ans=1+2+\cdots+45=1035`。

第 6 题(单选题,2 分)

给定一个空栈,支持入栈和出栈操作。将 1 至 10 依次入栈,第一个出栈的数为 8,则第二个出栈的数不可能为( )。

A.
1
B.
7
C.
9
D.
10

正确答案A

解析详情
答案 A栈的出栈序列
思路与推导
  1. 首次弹出 8 后,栈顶是 7;此后可以直接弹出 7,也可以先压入并弹出 9 或 10,但不可能越过 7 到 2 而让 1 第二个出栈。

第 7 题(单选题,2 分)

有序表中有 100 个元素,使用二分法查找元素 X。有( )个数可以通过恰好 5 次查找找到。

A.
100
B.
32
C.
31
D.
16

正确答案D

解析详情
答案 D二分查找
思路与推导
  1. 二分查找的比较过程形成二叉判定树,第 5 层有 24=162^{4}=16 个位置,因此恰好比较 5 次找到的元素有 16 个。

第 8 题(单选题,2 分)

下面的表格是无向图 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
A.
1
B.
2
C.
3
D.
4

正确答案D

解析详情
答案 D邻接矩阵与顶点度
思路与推导
  1. 无向图中顶点的度等于邻接矩阵对应行中 1 的个数;C 行有 4 个 1,为最大值。

第 9 题(单选题,2 分)

8 支队伍均分为第一组与第二组进行小组赛。A 队和 B 队在同一组,而与 C 队不在同一组的分组方案数有( )种。

A.
10
B.
20
C.
30
D.
40

正确答案B

解析详情
答案 B组合计数
思路与推导
  1. 第一、第二组有标签。A、B 可同在任一组,再从除 C 外的 5 支队伍中选 2 支同组,方案数为 2(52)=202\binom{5}{2}=20。

第 10 题(单选题,2 分)

将一根长度为 3 的木棍折为三段,当断点的位置在木棍中等概率分布时,三段木棍可以构成三角形的概率为( )。

A.
1
B.
0.5
C.
0.25
D.
0.125

正确答案C

解析详情
答案 C几何概率
思路与推导
  1. 两个断点把长度归一化后,三段能成三角形等价于最长一段小于 1/21/2;在两个断点的单位正方形样本空间中,满足条件区域面积占 1/41/4。

第 11 题(单选题,2 分)

下列关于快速排序的说法中,不正确的是( )。

A.
快速排序典型地应用了分治法的思想。
B.
快速排序的最坏时间复杂度为 O(nlog⁡n)O(n\log n)。
C.
快速排序是基于交换的排序。
D.
`sort` 函数是 STL 提供的快排函数,同时结合了堆排序、插入排序等技术。

正确答案B

解析详情
答案 B快速排序复杂度
思路与推导
  1. 快速排序在划分极不均衡时会退化为 T(n)=T(n−1)+O(n)T(n)=T(n-1)+O(n),最坏时间复杂度是 O(n2)O(n^2),因此 B 不正确。

第 12 题(单选题,2 分)

关于整数的各种 8 位二进制编码方法,说法错误的是( )。

A.
-17 的原码为 `10010001`。
B.
22 的补码为 `00010110`。
C.
-13 的反码为 `11110010`。
D.
以上说法存在错误。

正确答案D

解析详情
答案 D原码、反码与补码
思路与推导
  1. -17 的原码是 `10010001`,22 的补码是 `00010110`,-13 的反码是 `11110010`,A、B、C 均正确,所以“以上说法存在错误”本身错误。

第 13 题(单选题,2 分)

表达式 (x−2x−1/2)4(x-2x^{-1/2})^4 中,xx 的系数为( )。

A.
12
B.
-12
C.
24
D.
-24

正确答案C

解析详情
答案 C二项式展开
思路与推导
  1. 取两次 −2x−1/2-2x^{-1/2} 时幂次为 x2⋅x−1=xx^{2}\cdot x^{-1}=x,其系数为 (42)(−2)2=24\binom{4}{2}(-2)^2=24。

第 14 题(单选题,2 分)

二叉树 T 的中序遍历为 `CGEADBF`,后序遍历为 `GECDFBA`,则其前序遍历为( )。

A.
ACEGBDF
B.
ACGEBDF
C.
ABDFCEG
D.
ABCDEFG

正确答案A

解析详情
答案 A二叉树遍历还原
思路与推导
  1. 后序末尾确定根为 A;由中序划分可还原左子树前序为 `CEG`、右子树前序为 `BDF`,所以整树前序为 `ACEGBDF`。

第 15 题(单选题,2 分)

2024 年,来自谷歌 DeepMind 的米斯·哈萨比斯和约翰·江珀获得了( ),以表彰他们在人工智能方面的贡献。

A.
王选奖
B.
图灵奖
C.
诺贝尔奖
D.
贝尔奖

正确答案C

解析详情
答案 C科技奖项
思路与推导
  1. 米斯·哈萨比斯和约翰·江珀获得了 2024 年诺贝尔化学奖,因此选择“诺贝尔奖”。

二、阅读程序(1)

 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` 均为不超过 10610^6 的正整数,且满足 l≤rl\le r,完成下面的判断题和单选题。

第 16 题(判断题,1.5 分)

当输入为 `2 5` 时,程序的输出为 `2 8`。( )

正确答案正确

解析详情
答案 正确位运算判定 2 的幂
思路与推导
  1. 条件 `(i & (i - 1)) != 0` 选中非 2 的幂。区间 2~5 中只有 3、5 被计入,数量为 2、和为 8。

第 17 题(判断题,1.5 分)

程序的输出总是两个正整数。( )

正确答案错误

解析详情
答案 错误边界输出
思路与推导
  1. 若区间只包含一个 2 的幂,例如输入 `1 1`,没有元素被计入,程序输出 `0 0`,并非两个正整数。

第 18 题(判断题,1.5 分)

将第 8 行的 `long long` 改为 `int`,程序行为不变。( )

正确答案错误

解析详情
答案 错误整数溢出
思路与推导
  1. 当区间较大时,被累加元素的和可接近 101210^{12},超过 32 位 `int` 上限;改成 `int` 会发生溢出,程序行为会改变。

第 19 题(单选题,3 分)

当输入为 `1 100` 时,程序的输出为( )。

A.
`93 4923`
B.
`92 4823`
C.
`93 4823`
D.
`92 4923`

正确答案A

解析详情
答案 A区间统计
思路与推导
  1. 1~100 共 100 个数,其中 2 的幂有 1、2、4、8、16、32、64 共 7 个;故 `cnt=93`,`sum=5050-127=4923`。

第 20 题(单选题,3 分)

当输入为 `10000 1000000` 时,程序的第一个输出为( )。

A.
989993
B.
989994
C.
989995
D.
989996

正确答案C

解析详情
答案 C2 的幂计数
思路与推导
  1. 区间共有 1000000−10000+1=9900011000000-10000+1=990001 个数,其中 2 的幂为 2142^{14} 到 2192^{19} 共 6 个,因此首个输出为 990001−6=989995990001-6=989995。

二、阅读程序(2)

 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` 的正整数,完成下面的判断题和单选题。

第 21 题(判断题,1.5 分)

当输入为 `3 5 1 3 4` 时,程序的输出为 0。( )

正确答案错误

解析详情
答案 错误动态规划状态模拟
思路与推导
  1. 依次计算得到 `dp[0..5] = 0,1,0,3,4,3`,所以最终输出 `dp[5]=3`,不是 0。

第 22 题(判断题,2 分)

当输入的数组 `a` 为 `{1}` 且 `m` 为偶数时,程序的输出为 0。( )

正确答案正确

解析详情
答案 正确奇偶状态
思路与推导
  1. 当 `a={1}` 时,`dp[i]` 只依赖 `dp[i-1]`:奇数位置为 1,偶数位置为 0,因此偶数 `m` 输出 0。

第 23 题(判断题,1.5 分)

将第 16 行的条件 `i >= a[j] && dp[i - a[j]] == 0` 改为 `dp[i - a[j]] == 0`,程序可能会产生编译错误。( )

正确答案错误

解析详情
答案 错误数组越界与编译
思路与推导
  1. 删除 `i >= a[j]` 后,`i<a[j]` 时会访问负下标;代码仍可通过编译,但运行时发生越界和未定义行为,因此不是编译错误。

第 24 题(单选题,3 分)

当输入为 `4 13 1 2 3 4` 时,程序的输出为( )。

A.
0
B.
1
C.
2
D.
3

正确答案D

解析详情
答案 D取石子状态
思路与推导
  1. 可选步长为 1~4 时,输态是 5 的倍数;13≡3(mod5)13\equiv3\pmod5,最后一个能从输态 10 转移来的步长为 3,所以输出 3。

第 25 题(单选题,3 分)

当输入为 `7 1000 1 2 3 4 5 6 7` 时,程序的输出为( )。

A.
0
B.
1
C.
2
D.
3

正确答案A

解析详情
答案 A周期状态
思路与推导
  1. 步长为 1~7 时,输态是 8 的倍数。1000 能被 8 整除,因此 `dp[1000]=0`。

第 26 题(单选题,4 分)

当输入的数组 `a` 为 `{1,2,3,4,5}` 时,有( )个符合数据范围的整数 `m` 使得输出为 3。

A.
165
B.
166
C.
167
D.
168

正确答案B

解析详情
答案 B周期计数与数据范围
思路与推导
  1. 步长为 1~5 时,输出 3 恰在 m≡3(mod6)m\equiv3\pmod6。又因数组元素 5 必须不超过 `m`,需排除 m=3m=3;从 9 到 999 共 (999−9)/6+1=166(999-9)/6+1=166 个。

二、阅读程序(3)

 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` 是不超过 10610^6 的正整数,完成下面的判断题和选择题。

提示:伯特兰-切比雪夫定理:对任意 n>1n>1,存在质数 pp 使得 n<p<2nn<p<2n。

第 27 题(判断题,1.5 分)

程序将从 `input.txt` 读入数据,输出到 `output.txt`。( )

正确答案错误

解析详情
答案 错误freopen 重定向
思路与推导
  1. 第一条把标准输出以写模式重定向到 `input.txt`,第二条把标准输入以读模式重定向到 `output.txt`,方向与题目描述正好相反。

第 28 题(判断题,1.5 分)

交换程序的第 12 行和第 13 行,不会导致数组越界。( )

正确答案正确

解析详情
答案 正确数组边界
思路与推导
  1. 交换后会先写 `comp_by[x*primes[i]]` 再判断是否大于 `n`;首次越过 `n` 时乘数至多为 2,故下标不超过 2n≤20000002n\le2000000,仍小于数组长度 2000005。

第 29 题(判断题,1.5 分)

对于所有正整数 `i`,满足 1≤i≤n1\le i\le n,输出的第 `i` 个数是 0 当且仅当 `i` 是质数。( )

正确答案错误

解析详情
答案 错误质数筛与特殊值 1
思路与推导
  1. 筛法中质数位置保持 0,但 `comp_by[1]` 也为 0,而 1 不是质数,所以“当且仅当”不成立。

第 30 题(单选题,3 分)

该程序的主要流程最接近( )。

A.
递归法
B.
动态规划
C.
埃拉托斯特尼筛
D.
欧拉筛

正确答案D

解析详情
答案 D欧拉筛
思路与推导
  1. 程序按质数表枚举并在遇到 `x` 的最小质因子时停止,使每个合数按其最小质因子生成一次,属于欧拉筛。

第 31 题(单选题,3 分)

将程序的第 14 行移动到第 11 行,当输入为 1000000 时,输出的第( )个数会发生改变。

A.
75
B.
45
C.
97
D.
105

正确答案B

解析详情
答案 B欧拉筛语句顺序
思路与推导
  1. 把整除判断移到赋值之前后,`x=15` 遇到质数 3 会先退出,45 不再被标记,故第 45 个输出改变;75、105 仍可由更早的乘积标记,97 本来就是质数。

第 32 题(单选题,4 分)

当输入为 100 时,输出的所有数字之和为( )。

A.
154
B.
194
C.
197
D.
214

正确答案C

解析详情
答案 C最小质因子求和
思路与推导
  1. `comp_by` 保存合数的最小质因子。100 以内贡献分别为:偶合数 49×2=9849\times2=98,最小质因子为 3、5、7 的奇合数贡献 48、30、21,总和为 197。

三、完善程序(1)

(全排列检查)给定长度为 `n` 的数组 `a`,判断其是否构成全排列。如果 1,2,…,n1,2,\ldots,n 都恰好在数组 `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;
}

第 33 题(单选题,3 分)

① 处应填( )。

A.
a.length()
B.
a.size()
C.
a.back()
D.
a.capacity()

正确答案B

解析详情
答案 Bvector 长度
思路与推导
  1. 形参 `a` 是 `vector<int>`,元素个数由 `a.size()` 返回,因此 ① 填 `a.size()`。

第 34 题(单选题,3 分)

② 处应填( )。

A.
0
B.
n
C.
n + 1
D.
1000000000

正确答案C

解析详情
答案 C计数数组下标
思路与推导
  1. 程序会访问 `count[1]` 到 `count[n]`,所以需要 `n+1` 个元素,合法下标为 0~n。

第 35 题(单选题,3 分)

③ 处应填( )。

A.
1 <= a[i] && a[i] <= n
B.
1 <= a[i] <= n
C.
1 <= a[i] || a[i] <= n
D.
a[i] < 1 || a[i] > n

正确答案A

解析详情
答案 AC++ 范围判断
思路与推导
  1. 合法值必须同时满足 `1 <= a[i]` 和 `a[i] <= n`,应使用逻辑与连接两个比较。

第 36 题(单选题,3 分)

④ 处应填( )。

A.
break
B.
continue
C.
return true
D.
return false

正确答案D

解析详情
答案 D异常输入处理
思路与推导
  1. 一旦发现元素不在 1~n 范围内,数组不可能是全排列,应立即 `return false`。

第 37 题(单选题,3 分)

⑤ 处应填( )。

A.
i
B.
a[i]
C.
i - 1
D.
i / 2

正确答案A

解析详情
答案 A频次检查
思路与推导
  1. 循环变量 `i` 正在枚举数值 1~n,应检查对应的 `count[i]` 是否大于 1,所以 ⑤ 填 `i`。

三、完善程序(2)

(跳跃)给定一个数组 a[0],a[1],…,a[n−1]a[0],a[1],\ldots,a[n-1],每次跳跃从当前位置 `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;
}

第 38 题(单选题,3 分)

① 处应填( )。

A.
i
B.
a[i]
C.
0
D.
dp[i][1]

正确答案B

解析详情
答案 B倍增初始化
思路与推导
  1. `dp[i][0]` 表示从位置 `i` 跳 20=12^0=1 次后的编号,按定义就是 `a[i]`。

第 39 题(单选题,3 分)

② 处应填( )。

A.
dp[dp[i][k - 1]][k - 1]
B.
dp[i][k - 1] + dp[i][k - 1]
C.
dp[i - 1][k - 1]
D.
dp[k - 1][i]

正确答案A

解析详情
答案 A倍增转移
思路与推导
  1. 跳 2k2^k 次可拆成两段 2k−12^{k-1} 次,先到 `dp[i][k-1]`,再跳同样次数,因此转移为 `dp[dp[i][k-1]][k-1]`。

第 40 题(单选题,3 分)

③ 处应填( )。

A.
k & j
B.
k >> j
C.
(k >> j) & 1
D.
(k >> j) ^ 1

正确答案C

解析详情
答案 C二进制拆分
思路与推导
  1. 枚举第 `j` 位时,只有 `k` 的该位为 1 才执行对应的 2j2^j 次跳跃,条件应为 `(k >> j) & 1`。

第 41 题(单选题,3 分)

④ 处应填( )。

A.
dp[j][u]
B.
dp[k][u]
C.
dp[u][j]
D.
a[u]

正确答案C

解析详情
答案 C倍增查询
思路与推导
  1. 当第 `j` 位有效时,当前位置 `u` 应沿预处理表跳 2j2^j 次,更新为 `dp[u][j]`。

第 42 题(单选题,3 分)

⑤ 处应填( )。

A.
u
B.
x
C.
k
D.
dp[u][0]

正确答案A

解析详情
答案 A查询结果
思路与推导
  1. 循环结束后 `u` 已经累计完成 `k` 次跳跃,应该直接输出 `u`。