GESP 客观题评测系统

试卷解析 · 理解每一步

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

CSPJ-2026-R1-Mock-Luogu

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

一、单项选择题

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

第 1 题(单选题,2 分)

在 64 位计算机中,下列 C++ 基本类型中( )的单个变量占用的内存最大。

A.
`int`
B.
`bool`
C.
`double`
D.
`char`

正确答案C

解析详情
答案 CC++ 基本类型
思路与推导
  1. 在常见 64 位平台上,`double` 通常占 8 字节,`int` 占 4 字节,`bool` 和 `char` 通常各占 1 字节,因此选择 C。

第 2 题(单选题,2 分)

Ubuntu 是常见的 Linux 操作系统。假设当前登录的用户为 `luogu`,当前所在的工作目录为 `/home/luogu`,使用( )命令,可以在 `/home/sjtu/phd` 下新建子目录 `paper`。

A.
mv ./sjtu/phd/paper
B.
mkdir ~/sjtu/phd/paper
C.
mv /home/sjtu/phd/paper
D.
mkdir ../sjtu/phd/paper

正确答案D

解析详情
答案 DLinux 路径与目录命令
思路与推导
  1. 当前目录是 `/home/luogu`,`..` 表示 `/home`,所以 `mkdir ../sjtu/phd/paper` 会创建 `/home/sjtu/phd/paper`。

第 3 题(单选题,2 分)

阅读下面的代码,其中说法错误的是( )。

#include <bits/stdc++.h>
using namespace std;
stack<int> s1, s2;
int T, x;

int main() {
    cin >> T;
    while (T--) {
        string op;
        cin >> op;
        if (op == "in") {
            cin >> x;
            s1.push(x);
        } else {
            if (s2.empty()) {
                while (!s1.empty()) {
                    s2.push(s1.top());
                    s1.pop();
                }
            }
            cout << s2.top() << endl;
            s2.pop();
        }
    }
    return 0;
}
A.
代码中使用的 `stack` 是 STL 提供的栈的容器,栈的特点是先进后出。
B.
代码所实现的功能和队列的功能类似。
C.
输入为 `6 in 1 out in 2 in 3 out out` 时,输出为 `1 3 2`。
D.
若不对输入数据的操作类型做 `in` 和 `out` 数量的保证,代码存在运行时错误的风险。

正确答案C

解析详情
答案 C双栈模拟队列
思路与推导
  1. 第一次 `out` 输出 1;随后 2、3 转入 `s2` 后依次输出 2、3,因此实际输出是 `1 2 3`,C 的说法错误。

第 4 题(单选题,2 分)

(1C)16(1C)_{16}、(24)10(24)_{10}、(31)8(31)_8 和 (11011)2(11011)_2 中,最大的数的十进制表示为( )。

A.
28
B.
30
C.
25
D.
27

正确答案A

解析详情
答案 A进制转换
思路与推导
  1. 四个数换算为十进制依次是 28、24、25、27,最大值为 28。

第 5 题(单选题,2 分)

阅读下面的材料,完成本题。

在计算机底层,`int` 类型与 `unsigned int` 类型的加法运算在 ALU(算术逻辑单元)中的执行路径完全一致——ALU 仅对两个操作数进行二进制补码加法,得到相同的 32 位二进制和,并同时设置状态标志位(如进位标志 CF 和溢出标志 OF)。二者的差异仅在于如何解释这个二进制结果:若解释为有符号数(`int`),则按补码规则读取;若解释为无符号数(`unsigned int`),则按普通二进制数值读取,因此同一个二进制和可能对应不同的十进制值。当加法结果超出该类型的表示范围时,即发生溢出,ALU 并不会抛出异常或中断,而是直接截断高位,仅保留低 32 位作为结果,并更新标志位——对于无符号数溢出,ALU 将进位标志 CF 置 1(表示最高位产生进位),而对于有符号数溢出,ALU 将溢出标志 OF 置 1(表示符号位错误),但计算结果本身仍被保存为截断后的低 32 位,后续程序需根据类型和标志位自行判断是否发生了溢出,ALU 本身不对溢出做额外处理。

ALU 是算术逻辑单元,根据材料可以推断其属于( )的一部分。

A.
CPU
B.
外存
C.
内存
D.
操作系统

正确答案A

解析详情
答案 A计算机组成
思路与推导
  1. ALU 负责算术运算和逻辑运算,是 CPU 的核心组成部分之一。

第 6 题(单选题,2 分)

根据第 5 题前的材料,`int` 类型变量 `x` 的值为 -1,将其强制类型转换为 `unsigned int` 类型输出,输出的值为( )。

A.
-1
B.
2147483647
C.
4294967295
D.
4294967296

正确答案C

解析详情
答案 C有符号与无符号整数
思路与推导
  1. 32 位补码的 -1 全部位都是 1,按 `unsigned int` 解释时为 232−1=42949672952^{32}-1=4294967295。

第 7 题(单选题,2 分)

根据第 5 题前的材料,下面代码的输出为( )。

#include <iostream>

int main() {
    unsigned int a = 2147483648;
    int b = 1234567890;
    std::cout << int(a + b) << std::endl;
}
A.
3382051538
B.
-912915758
C.
1234567889
D.
每一次运行输出可能不同

正确答案B

解析详情
答案 B无符号运算与补码解释
思路与推导
  1. `a+b=3382051538`,其 32 位结果按有符号补码解释为 3382051538−232=−9129157583382051538-2^{32}=-912915758。

第 8 题(单选题,2 分)

下面的表格是图 G 的邻接表,关于图 G 说法错误的是( )。

1  2 3 4 5
2  1 3
3  1 2 6
4  1 5
5  1 4
6  3
A.
图 G 可能是无向图。
B.
图 G 中度最大的结点为结点 1。
C.
图 G 中共有 2 个连通块。
D.
可以使用 `vector` 实现图 G 的邻接表结构。

正确答案C

解析详情
答案 C邻接表与连通性
思路与推导
  1. 邻接关系成对出现,图可以是无向图;结点 1 的度为 4 且所有结点都可由 1 连通,因此只有 1 个连通块,C 错误。

第 9 题(单选题,2 分)

下列代码的输出为( )。

#include <iostream>
using namespace std;

int main() {
    int A = 1, B = 1;
    int& a = A, b = B;
    a = 2, b = 2;
    std::cout << A << ' ' << B << std::endl;
}
A.
`1 1`
B.
`1 2`
C.
`2 1`
D.
`2 2`

正确答案C

解析详情
答案 CC++ 引用声明
思路与推导
  1. 声明中只有 `a` 是 `A` 的引用,`b` 是由 `B` 初始化的普通 `int`。赋值后 `A=2`、`B=1`,输出 `2 1`。

第 10 题(单选题,2 分)

给定一个长度为 nn 的数列 A=[a1,a2,…,an]A=[a_1,a_2,\ldots,a_n],从中选择若干个元素,并保持它们在原数列中的相对顺序不变,组成一个新序列 B=[b1,b2,…,bk]B=[b_1,b_2,\ldots,b_k]。若该新序列满足 b1<b2<⋯<bkb_1<b_2<\cdots<b_k,则称 BB 为原数列的一个上升子序列。在所有可能的上升子序列中,长度 kk 达到最大值的那个,称为该数列的最长上升子序列(LIS)。下列方法中,( )不能正确求解一个序列的最长上升子序列。

A.
贪心。从第 1 个数开始选择,每次选取比上一个数更大的最小的数。
B.
搜索。通过深度优先搜索,枚举每一个数应该选哪一个。
C.
动态规划。用 dp[i]dp[i] 表示以 aia_i 结束的最长上升子序列的长度。此时有 dp[i]=max⁡(dp[j])+1dp[i]=\max(dp[j])+1,其中 jj 满足 1≤j<i1\le j<i 且 aj<aia_j<a_i。
D.
动态规划。用 dp[i]dp[i] 表示长度为 ii 的上升子序列中,结尾数值可以取得的最小值。枚举 aja_j,每次二分查找到 dp[i]dp[i] 大于等于 aja_j 的最小的 ii,将 dp[i]dp[i] 设置为 aja_j。

正确答案A

解析详情
答案 A最长上升子序列
思路与推导
  1. 从第一个数开始的贪心会漏解,例如序列 `5,1,2,3,4` 被迫先选 5,只得到长度 1,而真实 LIS 长度为 4。

第 11 题(单选题,2 分)

哈夫曼编码是实现信息压缩的常见编码方式。假设有一组字符 {a,b,c,d,e,f}\{a,b,c,d,e,f\},对应的频率分别为 0.05、0.09、0.12、0.13、0.16、0.45。那么字符串 `abcdef` 共有( )种可能的哈夫曼编码。

A.
8
B.
16
C.
32
D.
64

正确答案C

解析详情
答案 C哈夫曼编码
思路与推导
  1. 6 个叶子构成的哈夫曼树有 5 个内部结点;每个内部结点的左右子树均可交换,故共有 25=322^5=32 种编码。

第 12 题(单选题,2 分)

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

A.
`EACDBGF`
B.
`ECADBGF`
C.
`EACBDGF`
D.
`EACDFGB`

正确答案A

解析详情
答案 A二叉树遍历还原
思路与推导
  1. 后序末尾确定根为 E;左子树由中序 `CADB`、后序 `CBDA` 得到前序 `ACDB`,右子树前序为 `GF`,故总前序为 `EACDBGF`。

第 13 题(单选题,2 分)

在 1 到 200 的正整数中,能被 3 或 5 整除,但不能被 7 整除的整数共有( )个。

A.
79
B.
80
C.
81
D.
93

正确答案B

解析详情
答案 B容斥原理
思路与推导
  1. 能被 3 或 5 整除的数有 66+40−13=9366+40-13=93 个;其中还能被 7 整除的有 9+5−1=139+5-1=13 个,所以答案是 93−13=8093-13=80。

第 14 题(单选题,2 分)

数字 1、2、3、4、5、6 排成一列,要求奇数之间的相对顺序保持不变,偶数之间的相对顺序也保持不变,则共有( )种不同的排列。

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

正确答案B

解析详情
答案 B保持相对顺序的排列
思路与推导
  1. 奇数序列 `1,3,5` 和偶数序列 `2,4,6` 的内部顺序固定,只需从 6 个位置中选 3 个放奇数,共 (63)=20\binom{6}{3}=20 种。

第 15 题(单选题,2 分)

大语言模型(LLMs)技术发展日新月异。关于 LLM 与 CCF 有关活动,说法不正确的是( )。

A.
CCF 在 NOI 冬令营等活动中开展了 LLM 协助编程的试点比赛。
B.
CCF 主办了大模型能力认证 LMCC。
C.
CCF SPP 系列活动中举办了一系列紧贴 LLM 的讲座。
D.
CSP-J/S 第一轮中,选手可以使用 LLM 辅助完成试题。

正确答案D

解析详情
答案 D竞赛规则
思路与推导
  1. CSP-J/S 第一轮是受监管的认证考试,选手不能使用 LLM 辅助完成试题,因此 D 的说法不正确。

二、阅读程序(1)

 1 | #include <iostream>
 2 | using namespace std;
 3 |
 4 | bool isPrime(int n) {
 5 |     for (int i = 2; i < n; ++i) {
 6 |         if (n % i == 0) {
 7 |             return false;
 8 |         }
 9 |     }
10 |     return true;
11 | }
12 |
13 | int main() {
14 |     int n;
15 |     cin >> n;
16 |     for (int i = 2; i + 2 <= n; ++i) {
17 |         if (isPrime(i) && isPrime(i + 2)) {
18 |             cout << i << " " << i + 2 << endl;
19 |         }
20 |     }
21 |     return 0;
22 | }

假设输入的 `n` 是 5 到 1000 之间的正整数,完成下面的判断题和单选题。

第 16 题(判断题,1.5 分)

当输入为 14 时,输出的所有整数之和为 44。( )

正确答案正确

解析详情
答案 正确质数与孪生质数
思路与推导
  1. 输入 14 时输出 `(3,5)`、`(5,7)`、`(11,13)`,所有整数之和为 3+5+5+7+11+13=443+5+5+7+11+13=44。

第 17 题(判断题,1.5 分)

将第 16 行的 `int i = 2` 修改为 `int i = 1`,程序输出不变。( )

正确答案错误

解析详情
答案 错误函数边界条件
思路与推导
  1. 原函数会把 1 错判为质数。循环从 1 开始后会额外输出 `(1,3)`,所以程序输出发生变化。

第 18 题(判断题,1.5 分)

无论输入为多少,输出的所有整数均为奇数。( )

正确答案正确

解析详情
答案 正确孪生质数奇偶性
思路与推导
  1. 2 是唯一偶质数,但 `(2,4)` 不是孪生质数对;程序实际输出的孪生质数都大于 2,因此均为奇数。

第 19 题(单选题,3 分)

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

A.
220
B.
224
C.
227
D.
230

正确答案B

解析详情
答案 B程序模拟
思路与推导
  1. 不超过 50 的输出数对为 `(3,5)`、`(5,7)`、`(11,13)`、`(17,19)`、`(29,31)`、`(41,43)`,总和为 224。

第 20 题(单选题,3 分)

将第 5 行的 `i < n` 修改为以下哪个时,程序输出不变?( )

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

正确答案C

解析详情
答案 C试除法判质数
思路与推导
  1. 判断合数只需试除到平方根,并且完全平方数的平方根必须被检查,所以条件应为 `i * i <= n`。

二、阅读程序(2)

 1 | #include <iostream>
 2 | #include <string>
 3 | #include <vector>
 4 | #include <algorithm>
 5 | using namespace std;
 6 | int main() {
 7 |     string a, b;
 8 |     cin >> a >> b;
 9 |     int n = a.size(), m = b.size();
10 |     vector<vector<int>> dp(n + 1, vector<int>(m + 1, 0));
11 |     for (int i = 0; i <= n; ++i) {
12 |         for (int j = 0; j <= m; ++j) {
13 |             if (i == 0) {
14 |                 dp[i][j] = j;
15 |             }
16 |             else if (j == 0) {
17 |                 dp[i][j] = i;
18 |             }
19 |             else if (a[i - 1] == b[j - 1]) {
20 |                 dp[i][j] = dp[i - 1][j - 1] + 1;
21 |             }
22 |             else {
23 |                 dp[i][j] = min(dp[i - 1][j], dp[i][j - 1]) + 1;
24 |             }
25 |         }
26 |     }
27 |     cout << dp[n][m] << endl;
28 |     return 0;
29 | }

假设输入的 `a`、`b` 是长度不超过 1000 的仅包含小写字母的字符串,完成下面的判断题和单选题。

第 21 题(判断题,1.5 分)

若交换输入的 `a` 和 `b`,程序的输出一定不变。( )

正确答案正确

解析详情
答案 正确最短公共超序列
思路与推导
  1. 该 DP 计算两个字符串的最短公共超序列长度,交换两个字符串不会改变这一长度,因此输出不变。

第 22 题(判断题,1.5 分)

若对调代码第 10 行的 `n`、`m`,可能会造成程序运行时错误。( )

正确答案正确

解析详情
答案 正确二维数组边界
思路与推导
  1. 若只在第 10 行交换 `n`、`m`,数组维度与后续 `i<=n`、`j<=m` 的循环不再对应;当两长度不等时可能越界。

第 23 题(判断题,1.5 分)

程序的输出一定大于 min⁡{n,m}\min\{n,m\}。( )

正确答案错误

解析详情
答案 错误最短公共超序列
思路与推导
  1. 当 `a` 与 `b` 完全相同且长度相等时,输出就是该长度,等于 min⁡{n,m}\min\{n,m\},并非一定严格大于。

第 24 题(单选题,3 分)

当输入为 `aba bab` 时,程序的输出为( )。

A.
4
B.
5
C.
6
D.
7

正确答案A

解析详情
答案 A最短公共超序列
思路与推导
  1. `aba` 与 `bab` 的最长公共子序列长度为 2,因此最短公共超序列长度为 3+3−2=43+3-2=4。

第 25 题(单选题,3 分)

当输入为 `abcddd acbded` 时,程序的输出为( )。

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

正确答案B

解析详情
答案 B动态规划模拟
思路与推导
  1. 两个长度均为 6 的字符串有长度 4 的最长公共子序列,例如 `abdd`,所以输出为 6+6−4=86+6-4=8。

第 26 题(单选题,3 分)

假设输入的 `a`、`b` 都是长度为 2 且仅包含 `abcd` 四种字母的字符串。有多少种不同的有序字符串对 `a`、`b` 使得程序的输出为 3?( )

A.
16
B.
72
C.
84
D.
156

正确答案D

解析详情
答案 D组合计数
思路与推导
  1. 共有 162=25616^2=256 个有序字符串对。输出 2 的相同串有 16 对,完全没有公共字符的有 4×9+12×4=844\times9+12\times4=84 对,其余 256−16−84=156256-16-84=156 对输出 3。

二、阅读程序(3)

 1 | #include <iostream>
 2 | #include <string>
 3 | #include <algorithm>
 4 | using namespace std;
 5 | int n;
 6 | string s;
 7 | int dfs(string t, int lst) {
 8 |     int ret = 0;
 9 |     for (int i = 0; i <= n; i++)
10 |         if (t[i] != '1')
11 |             ret = 1e9;
12 |     if (ret == 0) return 0;
13 |     for (int i = 0; i <= n; i++)
14 |         if (i != lst && s.substr(n - i, i) == t.substr(0, i)) {
15 |             string cur = t;
16 |             cur[i] ^= 1;
17 |             ret = min(ret, dfs(cur, i) + 1);
18 |         }
19 |     return ret;
20 | }
21 | int main() {
22 |     cin >> s;
23 |     n = s.size();
24 |     string t0(n + 1, '0');
25 |     cout << dfs(t0, -1);
26 |     return 0;
27 | }

假设若无特殊说明,输入的字符串 `s` 是一个长度不超过 18 的非空 01 串,完成下面的判断题和单选题。字符 `0` 和 `a` 的 ASCII 码分别是 48 和 97。

第 27 题(判断题,1.5 分)

将第 11 行的 `1e9` 换成 `1234567`,程序的输出结果不变。( )

正确答案正确

解析详情
答案 正确递归状态空间
思路与推导
  1. 长度至多 18 时,程序涉及的 `t` 状态数量不超过 219=5242882^{19}=524288,有效返回值远小于 1234567;替换哨兵值不会改变最小值。

第 28 题(判断题,1.5 分)

将第 14 行的 `if` 语句中,`i != lst &&` 去掉,程序的输出结果不变。( )

正确答案错误

解析详情
答案 错误递归防回退
思路与推导
  1. 第 `i` 次操作只翻转 `t[i]`,不会改变长度为 `i` 的前缀条件;去掉 `i != lst` 后可立即再次选择同一 `i` 翻转回来,形成递归循环。

第 29 题(单选题,3 分)

下列说法中正确的是( )。

A.
设输入 `10011101010` 和 `01100010101` 得到的结果分别为 aa、bb,那么 a<ba<b。
B.
存在一种输入,使得程序发生自然溢出。
C.
把第 16 行改成 `cur[i] = 'a' - cur[i];`,程序的输出结果会改变。
D.
前三个选项都不对。

正确答案D(另接受:B)

解析详情
答案 D字符运算与递归验证
思路与推导
  1. 两组指定输入的输出都为 168;按题面“自然溢出”的字面含义,递归结果不会产生 `int` 溢出;且 `'a'-'0'='1'`、`'a'-'1'='0'`,与 `^=1` 的翻转效果相同,所以主答案为 D。若原文实际想表达“栈溢出”,则 B 也可成立,系统兼容该答案。

第 30 题(单选题,3 分)

假设输入为 `00000001`,那么程序的输出为( )。

A.
341
B.
342
C.
343
D.
ABC 均错

正确答案A

解析详情
答案 A递归状态枚举
思路与推导
  1. 把 `t` 视为 9 位状态,按第 14 行的合法转移逐层计算,初始状态到全 1 状态的返回值为 341。

第 31 题(单选题,3 分)

假设输入为 `110111011110111110`,那么函数 `dfs` 将被调用( )次。

A.
2182^{18}
B.
2192^{19}
C.
2202^{20}
D.
ABC 均错

正确答案B

解析详情
答案 B递归调用计数
思路与推导
  1. 对给定的 18 位输入精确展开递归树,连同初始调用共调用 `dfs` 524288 次,即 2192^{19} 次。

第 32 题(单选题,4 分)

假设输入为 `001000100001000001`,那么程序的输出为( )。

A.
21
B.
289746
C.
525739
D.
ABC 均错

正确答案D

解析详情
答案 D递归程序模拟
思路与推导
  1. 对给定输入按合法状态转移计算,程序返回 289745;它不等于 21、289746 或 525739,因此选择“ABC 均错”。

三、完善程序(1)

(序列第 kk 小)给出一个长度为 nn 的数列 a1,a2,…,ana_1,a_2,\ldots,a_n 和一个正整数 kk,你需要输出第 kk 小的数字。输入保证 1≤k≤n≤1051\le k\le n\le10^5,1≤ai≤2×1091\le a_i\le2\times10^9,且 aia_i 均为整数。下面的程序采用二分答案的方法,通过二分法找到最小的 xx,使得至少 kk 个数字不超过 xx。试补全程序。

#include <iostream>
using namespace std;

int n, k, a[100'005];

bool check(int x) {
    int c = 0;
    for (int i = 1; i <= n; i++)
        if (/* ① */)
            c++;
    return /* ② */;
}

int main() {
    cin >> n >> k;
    for (int i = 1; i <= n; i++)
        cin >> a[i];
    int l = 1, r = /* ③ */;
    while (l < r) {
        int x = /* ④ */;
        if (check(x))
            r = x;
        else
            /* ⑤ */;
    }
    cout << l << endl;
    return 0;
}

第 33 题(单选题,3 分)

① 处应填( )。

A.
a[i] <= x
B.
a[i] < x
C.
x <= a[i]
D.
x < a[i]

正确答案A

解析详情
答案 A二分答案判定
思路与推导
  1. `check(x)` 要统计不超过 `x` 的元素个数,所以条件应为 `a[i] <= x`。

第 34 题(单选题,3 分)

② 处应填( )。

A.
c <= k
B.
c < k
C.
k <= c
D.
k < c

正确答案C

解析详情
答案 C二分答案判定
思路与推导
  1. 当至少有 `k` 个元素不超过 `x` 时,`x` 才是可行上界,因此返回条件是 `k <= c`。

第 35 题(单选题,3 分)

③ 处应填( )。

A.
n
B.
a[n]
C.
1 << 32
D.
2e9

正确答案D

解析详情
答案 D二分边界
思路与推导
  1. 所有 ai≤2×109a_i\le2\times10^9,因此 `r=2e9` 一定覆盖答案;`a[n]` 未经排序,不能保证是上界。

第 36 题(单选题,3 分)

④ 处应填( )。

A.
(l + r) / 2
B.
(l + r + 1) >> 1
C.
l + (r - l) >> 1
D.
l + (r - l) / 2

正确答案D

解析详情
答案 D二分中点与溢出
思路与推导
  1. 需要向下取整的中点,`l + (r - l) / 2` 与目标一致且避免 `l+r` 超出 32 位 `int`,所以选 D。

第 37 题(单选题,3 分)

⑤ 处应填( )。

A.
l = x + 1
B.
l = x
C.
break
D.
l += x

正确答案A

解析详情
答案 A二分区间更新
思路与推导
  1. 当 `check(x)` 为假时答案严格大于 `x`,应令 `l=x+1`,从搜索区间中排除 `x`。

三、完善程序(2)

(走迷宫)有一个 n×mn\times m 的网格迷宫。记第 ii 行第 jj 列的格子为 (i,j)(i,j)。迷宫由空地(用 `.` 表示)和墙壁(用 `#` 表示)组成。起点是 (1,1)(1,1),终点是 (n,m)(n,m),保证起点和终点都是空地。小 R 希望使用两种操作从起点到达终点:

- 步行:移动到上下左右相邻的空地。 - 传送:移动到上下左右距离为 2 的空地。中间跨越的格子可以是空地也可以是墙壁。

小 R 最多使用 kk 次传送。请计算她到达终点的最少操作次数。如果无法到达,输出 -1。输入保证 1≤n,m≤1001\le n,m\le100,0≤k≤100\le k\le10。输入的 `grid[i][j]` 只有 `.` 和 `#` 两种字符。下面的程序使用广度优先搜索完成本题。试补全程序。

#include <bits/stdc++.h>
using namespace std;

const int MAXN = 105, MAXK = 15;
const int dx[4] = /* ① */;
const int dy[4] = {0, 0, -1, 1};
int n, m, k, dis[MAXN][MAXN][MAXK];
char grid[MAXN][MAXN];

struct Node {
    int x, y, k;
};

int bfs() {
    memset(dis, 0x3f, sizeof(dis));
    queue<Node> q;
    q.push({1, 1, 0});
    dis[1][1][0] = 0;
    while (/* ② */) {
        Node u = q.front();
        q.pop();
        if (u.x == n && u.y == m) {
            return /* ③ */;
        }
        for (int i = 0; i < 4; i++) {
            int nx = u.x + dx[i];
            int ny = u.y + dy[i];
            if (nx >= 1 && nx <= n && ny >= 1 && ny <= m && grid[nx][ny] != '#') {
                if (dis[nx][ny][u.k] > dis[u.x][u.y][u.k] + 1) {
                    dis[nx][ny][u.k] = dis[u.x][u.y][u.k] + 1;
                    q.push({nx, ny, u.k});
                }
            }
        }
        if (/* ④ */) {
            for (int i = 0; i < 4; i++) {
                int nx = u.x + dx[i] * 2;
                int ny = u.y + dy[i] * 2;
                int nk = u.k + 1;
                if (nx >= 1 && nx <= n && ny >= 1 && ny <= m && grid[nx][ny] != '#') {
                    if (dis[nx][ny][nk] > dis[u.x][u.y][u.k] + 1) {
                        dis[nx][ny][nk] = dis[u.x][u.y][u.k] + 1;
                        /* ⑤ */;
                    }
                }
            }
        }
    }
    return -1;
}

int main() {
    cin >> n >> m >> k;
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= m; j++) {
            cin >> grid[i][j];
        }
    }
    cout << bfs() << endl;
    return 0;
}

第 38 题(单选题,3 分)

① 处应填( )。

A.
{0, 0, -1, 1}
B.
{0, -1, 1, 0}
C.
{-1, 1, 0, 0}
D.
{-1, 1, -1, 1}

正确答案C

解析详情
答案 C网格方向数组
思路与推导
  1. `dy={0,0,-1,1}` 已表示左右方向,对应的 `dx` 应为 `{-1,1,0,0}`,共同覆盖上下左右。

第 39 题(单选题,3 分)

② 处应填( )。

A.
!q.empty()
B.
!q.size()
C.
!q.clear()
D.
q.front()

正确答案A

解析详情
答案 A广度优先搜索队列
思路与推导
  1. BFS 应在队列非空时继续处理结点,因此循环条件是 `!q.empty()`。

第 40 题(单选题,3 分)

③ 处应填( )。

A.
dis[u.x][u.y][u.k] + 1
B.
dis[u.x][u.y][u.k]
C.
dis[u.x][u.y][k]
D.
dis[u.x][u.y][0]

正确答案B

解析详情
答案 BBFS 最短路
思路与推导
  1. 结点第一次从 BFS 队列取出时,其 `dis[u.x][u.y][u.k]` 已是对应状态的最短操作次数,到达终点应直接返回该值。

第 41 题(单选题,3 分)

④ 处应填( )。

A.
u.k == k
B.
u.k > 0
C.
u.k <= k
D.
u.k < k

正确答案D

解析详情
答案 D状态扩展限制
思路与推导
  1. 只有已经使用的传送次数 `u.k` 小于上限 `k` 时,才能继续使用一次传送,因此条件是 `u.k < k`。

第 42 题(单选题,3 分)

⑤ 处应填( )。

A.
q.push(nx, ny, nk)
B.
q.push_back({nx, ny, nk})
C.
q.insert({nx, ny, nk})
D.
q.push({nx, ny, nk})

正确答案D

解析详情
答案 DC++ queue 入队
思路与推导
  1. 队列元素类型是 `Node`,应使用 `q.push({nx, ny, nk})` 把新的状态入队。