GESP 客观题评测系统

试卷解析 · 理解每一步

CSP-J 2026 第一轮模拟卷 AI-3(按 2025 卷型)

CSPJ-2026-R1-Mock-AI-3

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

一、单项选择题

共 15 题,每题 2 分,共 30 分。每题有且仅有一个正确选项。

第 1 题(单选题,2 分)

在 Linux 终端中,若要把源文件 main.cpp 编译为名为 train 的可执行文件,正确的命令是( )。

A.
g++ main.cpp -o train
B.
g++ train -o main.cpp
C.
./main.cpp train
D.
g++ main.cpp > train

正确答案A

解析详情
答案 Ag++ 编译输出文件
思路与推导
  1. g++ 的 -o 选项指定输出文件名,因此源文件在前,-o 后写 train。重定向符号 > 只重定向标准输出,不能代替 -o。

第 2 题(单选题,2 分)

640 个二进制位恰好占用( )字节。

A.
64
B.
72
C.
80
D.
512

正确答案C

解析详情
答案 C位与字节
思路与推导
  1. 1 字节等于 8 位,所以 640÷8=80 字节。

第 3 题(单选题,2 分)

二进制数 (11010110)₂ 对应的十六进制数是( )。

A.
(C6)₁₆
B.
(D6)₁₆
C.
(D3)₁₆
D.
(E6)₁₆

正确答案B

解析详情
答案 B二进制与十六进制转换
思路与推导
  1. 从右向左每 4 位分组:1101 对应 D,0110 对应 6,所以结果为 D6。

第 4 题(单选题,2 分)

以下 C++14 程序片段的输出是( )。

int a = 17, b = 5;
cout << (a / b + a % b * 2 > 8);
A.
1
B.
7
C.
8
D.
0

正确答案D

解析详情
答案 D算术与关系运算优先级
思路与推导
  1. 整数除法 17/5=3,取模 17%5=2,先算乘法得到 2×2=4,再得 3+4=7。关系表达式 7>8 为 false,cout 输出 0。

第 5 题(单选题,2 分)

以下 C++14 程序的输出是( )。

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

正确答案C

解析详情
答案 C值传递与引用传递
思路与推导
  1. x 是值形参,函数内变为 5 但不改变 a;y 是 b 的引用,执行 y+=x 后 b=4+5=9,因此输出 3 9。

第 6 题(单选题,2 分)

以下 C++14 程序片段的输出是( )。

vector<int> v = {2, 5};
v.push_back(7);
v[0] += v.back();
v.pop_back();
cout << v.size() << " " << v[0];
A.
2 9
B.
3 9
C.
2 7
D.
3 7

正确答案A

解析详情
答案 Avector 基本操作
思路与推导
  1. push_back 后为 {2,5,7},v[0] 加上末元素后变为 9;pop_back 删除 7,剩余两个元素,所以输出 2 9。

第 7 题(单选题,2 分)

栈 s 和队列 q 初始均为空。执行以下代码后的输出是( )。

s.push(3); s.push(7);
q.push(4); q.push(6);
cout << s.top() + q.front();
s.pop(); q.pop();
cout << " " << s.top() + q.front();
A.
11 7
B.
11 9
C.
10 9
D.
9 11

正确答案B

解析详情
答案 B栈与队列操作
思路与推导
  1. 第一次访问栈顶 7 与队首 4,和为 11。各弹出一个元素后,栈顶为 3、队首为 6,和为 9。

第 8 题(单选题,2 分)

一棵完全二叉树按层序从 1 开始给结点编号,共有 26 个结点。编号为 13 的结点( )。

A.
有编号为 25 和 26 的两个孩子
B.
只有编号为 27 的右孩子
C.
没有孩子
D.
只有编号为 26 的左孩子

正确答案D

解析详情
答案 D完全二叉树数组下标
思路与推导
  1. 1 起始编号时,结点 i 的左右孩子编号分别为 2i 和 2i+1。对 i=13,26 存在而 27>26 不存在,因此只有左孩子 26。

第 9 题(单选题,2 分)

某无向简单图的邻接矩阵如下。顶点 4 的度数为( )。

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

正确答案C

解析详情
答案 C顶点度数
思路与推导
  1. 顶点 4 对应第 4 行,其中第 1、2、5 列为 1,共连接 3 条边,所以度数为 3。

第 10 题(单选题,2 分)

当 n 为正整数时,以下代码片段的时间复杂度是( )。

for (int i = 1; i <= n; i *= 2)
    for (int j = 0; j < n; ++j)
        ++cnt;
A.
O(log n)
B.
O(n log n)
C.
O(n²)
D.
O(2ⁿ)

正确答案B

解析详情
答案 B时间复杂度
思路与推导
  1. 外层 i 每次乘 2,共执行 O(log n) 轮;每轮内层执行 n 次,总次数为 O(n log n)。

第 11 题(单选题,2 分)

关于从小到大的直接插入排序,下列说法正确的是( )。

A.
每轮把当前元素插入已排序前缀,最坏时间复杂度为 O(n²)
B.
每轮从未排序区间选最小元素,最坏时间复杂度为 O(n)
C.
必须额外使用长度为 n 的辅助数组
D.
它的基本操作是交换相邻逆序元素直到一轮不再交换

正确答案A

解析详情
答案 A直接插入排序
思路与推导
  1. 直接插入排序维护一个已排序前缀,把当前元素插入适当位置;逆序输入会产生约 n²/2 次移动,最坏复杂度为 O(n²)。B 描述选择排序,D 描述冒泡排序。

第 12 题(单选题,2 分)

调用 f(7) 时,函数 f 被调用的总次数(包含第一次调用和基例调用)是( )。

void f(int n) {
    if (n == 0) return;
    f(n - 1);
}
A.
6
B.
7
C.
14
D.
8

正确答案D

解析详情
答案 D递归调用次数
思路与推导
  1. 调用参数依次为 7,6,5,4,3,2,1,0,共 8 次。

第 13 题(单选题,2 分)

使用欧几里得算法计算 gcd(414,276),结果是( )。

A.
46
B.
69
C.
138
D.
207

正确答案C

解析详情
答案 C欧几里得算法
思路与推导
  1. 414 mod 276=138,276 mod 138=0,因此最大公因数是最后一个非零余数 138。

第 14 题(单选题,2 分)

数组 a 的下标从 1 开始,p[i]=a[1]+⋯+a[i],且 p[0]=0。区间 a[2]+⋯+a[5] 应表示为( )。

A.
p[5]-p[2]
B.
p[5]-p[1]
C.
p[6]-p[2]
D.
p[4]-p[1]

正确答案B

解析详情
答案 B前缀和
思路与推导
  1. p[5] 含 a[1] 到 a[5],减去 p[1]=a[1] 后恰好剩 a[2] 到 a[5]。

第 15 题(单选题,2 分)

从 7 名学生中选出 3 人组成小组,并在小组内指定 1 名组长和 1 名记录员,且两种角色不能由同一人担任。不同方案共有( )种。

A.
210
B.
35
C.
42
D.
105

正确答案A

解析详情
答案 A组合计数
思路与推导
  1. 先选 3 人有 C(7,3)=35 种,再从组内选组长有 3 种、选不同的记录员有 2 种。乘法原理得 35×3×2=210。

二、阅读程序(1)

假设 1≤n≤100000,且所有输入整数绝对值不超过 1000。阅读程序并回答问题。

 1 | #include <bits/stdc++.h>
 2 | using namespace std;
 3 | int main() {
 4 |     int n;
 5 |     cin >> n;
 6 |     vector<int> a(n);
 7 |     for (int i = 0; i < n; ++i) cin >> a[i];
 8 |     int best = 1, cur = 1;
 9 |     int turns = 0;
10 |     for (int i = 1; i < n; ++i) {
11 |         if (a[i] > a[i - 1]) {
12 |             ++cur;
13 |         } else {
14 |             best = max(best, cur);
15 |             cur = 1;
16 |         }
17 |         if (i >= 2) {
18 |             int x = a[i - 1] - a[i - 2];
19 |             int y = a[i] - a[i - 1];
20 |             if (x * y < 0) ++turns;
21 |         }
22 |     }
23 |     best = max(best, cur);
24 |     cout << best << " " << turns << "\n";
25 | }

第 16 题(判断题,1 分)

若 n=1,则程序输出的第一个数为 1。

正确答案正确

解析详情
答案 正确变量初始化与边界
思路与推导
  1. 循环不会执行,best 初值为 1,末尾更新仍为 1,因此第一个输出为 1。

第 17 题(判断题,1.5 分)

每次处理完下标 i 后,cur 表示以 a[i] 结尾的连续严格递增段长度。

正确答案正确

解析详情
答案 正确连续严格递增段
思路与推导
  1. 若 a[i]>a[i-1],原递增段延长 1;否则以 a[i] 重新开始长度为 1 的段。因此该不变量始终成立。

第 18 题(判断题,1.5 分)

程序的时间复杂度是 O(n²)。

正确答案错误

解析详情
答案 错误线性扫描复杂度
思路与推导
  1. 输入循环和主循环都只线性扫描一次,每轮工作为常数,总时间复杂度为 O(n),不是 O(n²)。

第 19 题(单选题,3 分)

输入如下时,程序输出是( )。

8
1 3 5 4 2 2 6 9
A.
2 1
B.
3 2
C.
3 1
D.
4 1

正确答案C

解析详情
答案 C样例跟踪
思路与推导
  1. 最长连续严格递增段为 1,3,5 或 2,6,9,长度均为 3。相邻差依次为 +2,+2,-1,-2,0,+4,+3,仅 +2 到 -1 的乘积小于 0,所以 turns=1。

第 20 题(单选题,3 分)

当某个中间元素两侧的相邻差都不为 0 时,该元素使 turns 增加的充分必要条件是( )。

A.
它大于前一个元素
B.
它严格大于两侧元素或严格小于两侧元素
C.
它等于两侧元素之一
D.
它所在的递增段长度为 1

正确答案B

解析详情
答案 B乘积符号判定转折
思路与推导
  1. turns 增加当且仅当前后两个差的乘积小于 0,即符号相反;这正对应中间元素是严格局部极大值或严格局部极小值。

第 21 题(单选题,3 分)

若输入序列含 6 个严格递减且互不相等的整数,则程序输出是( )。

A.
1 0
B.
1 4
C.
6 0
D.
6 4

正确答案A

解析详情
答案 A极端输入输出
思路与推导
  1. 每一步都不满足递增条件,cur 每次重置为 1,所以 best=1;所有相邻差都为负,任意相邻两个差乘积为正,turns=0。

二、阅读程序(2)

输入满足 1≤n,m≤30,起点坐标使用从 0 开始的行列编号。相邻格仅指上、下、左、右四个方向。阅读程序并回答问题。

 1 | #include <bits/stdc++.h>
 2 | using namespace std;
 3 | const int N = 35;
 4 | int h[N][N], dista[N][N];
 5 | int main() {
 6 |     int n, m, sx, sy;
 7 |     cin >> n >> m >> sx >> sy;
 8 |     for (int i = 0; i < n; ++i)
 9 |         for (int j = 0; j < m; ++j)
10 |             cin >> h[i][j];
11 |     queue<pair<int, int>> q;
12 |     for (int i = 0; i < n; ++i)
13 |         for (int j = 0; j < m; ++j)
14 |             dista[i][j] = -1;
15 |     dista[sx][sy] = 0;
16 |     q.push({sx, sy});
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 |         q.pop();
22 |         int x = cur.first, y = cur.second;
23 |         for (int k = 0; k < 4; ++k) {
24 |             int nx = x + dx[k], ny = y + dy[k];
25 |             if (nx < 0 || nx >= n || ny < 0 || ny >= m) continue;
26 |             if (dista[nx][ny] != -1) continue;
27 |             if (abs(h[nx][ny] - h[x][y]) > 2) continue;
28 |             dista[nx][ny] = dista[x][y] + 1;
29 |             q.push({nx, ny});
30 |         }
31 |     }
32 |     int cnt = 0, farthest = 0;
33 |     for (int i = 0; i < n; ++i)
34 |         for (int j = 0; j < m; ++j)
35 |             if (dista[i][j] != -1) {
36 |                 ++cnt;
37 |                 farthest = max(farthest, dista[i][j]);
38 |             }
39 |     cout << cnt << " " << farthest << "\n";
40 | }

第 22 题(判断题,1.5 分)

程序在把一个格子加入队列之前就写入其 dista 值,这可以避免同一格子被重复加入队列。

正确答案正确

解析详情
答案 正确BFS 入队标记
思路与推导
  1. 未访问格的 dista 为 -1;入队前立即改成非负值,之后其他相邻格再检查它时会直接跳过,因此每格至多入队一次。

第 23 题(判断题,1.5 分)

两个四方向相邻格子的高度差绝对值恰好为 2 时,程序允许从其中一个移动到另一个。

正确答案正确

解析详情
答案 正确可达条件
思路与推导
  1. 程序只在高度差绝对值大于 2 时跳过;恰好等于 2 不会跳过,因此允许双向移动。

第 24 题(判断题,1.5 分)

对每个可达格子,dista 中记录的是从起点出发、按程序移动规则到达该格子的最少步数。

正确答案正确

解析详情
答案 正确BFS 最短距离
思路与推导
  1. 每条移动边代价均为 1,队列按距离从小到大分层扩展;格子首次入队时得到的距离即最短距离。

第 25 题(单选题,3 分)

输入如下时,程序输出是( )。

3 4 0 0
1 2 4 9
2 4 5 8
7 6 5 7
A.
11 6
B.
12 7
C.
12 6
D.
10 7

正确答案B

解析详情
答案 BBFS 样例输出
思路与推导
  1. 所有 12 个格子均可达。最远的 (0,3) 可沿 (0,0)→(0,1)→(0,2)→(1,2)→(2,2)→(2,3)→(1,3)→(0,3) 到达,共 7 步,且不存在更短合法路径。

第 26 题(单选题,3 分)

忽略固定上界 N,程序关于 n、m 的时间复杂度是( )。

A.
O(n+m)
B.
O(nm log(nm))
C.
O(nm)
D.
O((nm)²)

正确答案C

解析详情
答案 C网格 BFS 复杂度
思路与推导
  1. 每个格子至多入队一次,每次只检查 4 个方向;初始化和汇总也各扫描一次网格,因此总时间为 O(nm)。

第 27 题(单选题,3 分)

对下面输入,若仅把第 27 行中的常数 2 改为 3,则 cnt 比原程序增加( )。

2 4 0 0
1 4 7 10
1 1 7 10
A.
2
B.
3
C.
4
D.
5

正确答案D

解析详情
答案 D规则变化后的可达性
思路与推导
  1. 原阈值 2 时只能到达左侧三个高度为 1 的格子,cnt=3。阈值改为 3 后可沿顶行 1→4→7→10,并进入相应下方格子,8 格全可达,增加 8-3=5。

二、阅读程序(3)

输入满足 1≤n≤200,1≤k≤输入中不同整数的个数。程序按结点数定义树高。阅读程序并回答问题。

 1 | #include <bits/stdc++.h>
 2 | using namespace std;
 3 | struct Node {
 4 |     int v;
 5 |     Node *left, *right;
 6 |     Node(int x) : v(x), left(nullptr), right(nullptr) {}
 7 | };
 8 | Node* insertNode(Node* p, int x) {
 9 |     if (p == nullptr) return new Node(x);
10 |     if (x < p->v) p->left = insertNode(p->left, x);
11 |     else if (x > p->v) p->right = insertNode(p->right, x);
12 |     return p;
13 | }
14 | int height(Node* p) {
15 |     if (p == nullptr) return 0;
16 |     return max(height(p->left), height(p->right)) + 1;
17 | }
18 | int leaves(Node* p) {
19 |     if (p == nullptr) return 0;
20 |     if (p->left == nullptr && p->right == nullptr) return 1;
21 |     return leaves(p->left) + leaves(p->right);
22 | }
23 | void inorder(Node* p, vector<int>& out) {
24 |     if (p == nullptr) return;
25 |     inorder(p->left, out);
26 |     out.push_back(p->v);
27 |     inorder(p->right, out);
28 | }
29 | int main() {
30 |     int n, k;
31 |     cin >> n >> k;
32 |     Node* root = nullptr;
33 |     for (int i = 0; i < n; ++i) {
34 |         int x;
35 |         cin >> x;
36 |         root = insertNode(root, x);
37 |     }
38 |     vector<int> order;
39 |     inorder(root, order);
40 |     cout << height(root) << " " << leaves(root) << " "
41 |          << order[k - 1] << "\n";
42 | }

第 28 题(判断题,1.5 分)

输入中重复出现的数值不会在这棵二叉搜索树中生成新的结点。

正确答案正确

解析详情
答案 正确BST 插入规则
思路与推导
  1. insertNode 只处理 x<p->v 和 x>p->v 两种情况;相等时直接返回原指针,因此重复值被忽略。

第 29 题(判断题,1.5 分)

按程序中 height 的定义,只含根结点的一棵树高度为 1。

正确答案正确

解析详情
答案 正确树高递归定义
思路与推导
  1. 根的左右空子树高度都是 0,返回 max(0,0)+1=1。

第 30 题(判断题,1.5 分)

执行 inorder 后,order 中的元素严格递增。

正确答案正确

解析详情
答案 正确中序遍历有序性
思路与推导
  1. 二叉搜索树满足左子树值小于根、右子树值大于根,且重复值未插入;中序遍历按左、根、右访问,所以序列严格递增。

第 31 题(单选题,3 分)

输入如下时,程序输出是( )。

9 5
12 5 18 2 9 15 21 7 16
A.
3 4 12
B.
4 3 12
C.
4 4 9
D.
4 4 12

正确答案D

解析详情
答案 D建树与递归统计输出
思路与推导
  1. 建树后最长根到叶路径含 4 个结点;叶结点为 2、7、16、21,共 4 个。中序序列为 2,5,7,9,12,15,16,18,21,第 5 个数是 12。

第 32 题(单选题,3 分)

若输入的 n 个数互不相同且严格递增,程序建树部分的最坏时间复杂度是( )。

A.
O(log n)
B.
O(n²)
C.
O(n log n)
D.
O(2ⁿ)

正确答案B

解析详情
答案 B最坏时间复杂度
思路与推导
  1. 严格递增输入使每个新结点都沿右孩子链走到底。第 i 次插入需 O(i) 时间,总和 1+2+⋯+(n-1)=O(n²)。

第 33 题(单选题,3 分)

依次插入 1~7 这 7 个互不相同的整数时,下列输入顺序能使程序计算出的树高为 3 的是( )。

A.
1 2 3 4 5 6 7
B.
4 2 6 1 3 5 7
C.
4 3 2 1 5 6 7
D.
7 1 6 2 5 3 4

正确答案B

解析详情
答案 B输入顺序与树高
思路与推导
  1. B 以 4 为根,2、6 为第二层,1、3、5、7 为第三层,树高恰为 3。A 退化为高度 7;C 和 D 都产生超过 3 层的链。

三、完善程序(1)环形窗口

给定一个含 n 个整数的环形序列和整数 k(1≤k≤n≤100000)。要从 n 个起点中选一个,求连续 k 个元素的最大和。输入元素绝对值不超过 10^9。请补全程序。

#include <bits/stdc++.h>
using namespace std;
const int N = 200005;
long long a[N], pre[N];
int main() {
    int n, k;
    cin >> n >> k;
    for (int i = 1; i <= n; ++i) {
        cin >> a[i];
        a[①] = a[i];
    }
    pre[0] = 0;
    for (int i = 1; i <= 2 * n; ++i)
        pre[i] = ②;
    long long best = LLONG_MIN;
    for (int l = 1; l <= n; ++l) {
        int r = ③;
        long long cur = ④;
        best = ⑤;
    }
    cout << best << "\n";
}

第 34 题(单选题,3 分)

①处应填( )。

A.
i + n
B.
i + k
C.
n - i + 1
D.
2 * i

正确答案A

解析详情
答案 A数组复制展开环
思路与推导
  1. 把原数组再复制一份到其后方,应令 a[i+n]=a[i],这样任何跨过末尾的长度 k 窗口都在线性数组中连续。

第 35 题(单选题,3 分)

②处应填( )。

A.
pre[i - 1] + a[i - 1]
B.
pre[i - 1] + a[i]
C.
pre[i] + a[i - 1]
D.
a[i] - pre[i - 1]

正确答案B

解析详情
答案 B前缀和递推
思路与推导
  1. pre[i] 表示 a[1] 到 a[i] 的和,因此递推式为 pre[i]=pre[i-1]+a[i]。

第 36 题(单选题,3 分)

③处应填( )。

A.
l + k
B.
l + n - 1
C.
l + k - 1
D.
(l + k) % n

正确答案C

解析详情
答案 C窗口右端点
思路与推导
  1. 闭区间 [l,r] 含 k 个元素满足 r-l+1=k,所以 r=l+k-1。复制展开后无需取模。

第 37 题(单选题,3 分)

为了由已经算好的 pre 数组在 O(1) 时间得到当前窗口 [l,r] 的元素和,④处应填( )。

A.
pre[2 * n] - pre[r]
B.
pre[r] - pre[l] + a[r]
C.
pre[r] - pre[l - 1]
D.
pre[r - l + 1]

正确答案C

解析详情
答案 C区间和公式
思路与推导
  1. pre[r] 包含 a[1] 到 a[r],减去窗口左侧的 a[1] 到 a[l-1],剩余部分恰为闭区间 [l,r] 的元素和。

第 38 题(单选题,3 分)

⑤处应填( )。

A.
max(best, cur)
B.
min(best, cur)
C.
max(best, (long long)r)
D.
best + cur

正确答案A

解析详情
答案 A最大值维护
思路与推导
  1. best 始终维护已检查窗口的最大元素和,所以应用 max(best,cur) 更新。

三、完善程序(2)最少硬币与方案恢复

给定 n 种正整数面值的硬币,每种硬币可使用任意次,求恰好凑出 target(1≤target≤10000)所需的最少硬币数,并输出一种方案;若无法凑出则输出 -1。请补全程序。

#include <bits/stdc++.h>
using namespace std;
const int INF = 1000000000;
int main() {
    int n, target;
    cin >> n >> target;
    vector<int> coin(n);
    for (int i = 0; i < n; ++i) cin >> coin[i];
    vector<int> dp(target + 1, INF);
    vector<int> last(target + 1, -1);
    ①;
    for (int x = 1; x <= target; ++x) {
        for (int j = 0; j < n; ++j) {
            if (②) {
                if (③) {
                    dp[x] = dp[x - coin[j]] + 1;
                    ④;
                }
            }
        }
    }
    if (dp[target] == INF) {
        cout << -1 << "\n";
        return 0;
    }
    cout << dp[target] << "\n";
    int x = target;
    while (x > 0) {
        cout << coin[last[x]]
             << (x == coin[last[x]] ? '\n' : ' ');
        ⑤;
    }
}

第 39 题(单选题,3 分)

①处应填( )。

A.
dp[target] = 0
B.
last[0] = 0
C.
dp[0] = 0
D.
dp[0] = INF

正确答案C

解析详情
答案 C一维动态规划初始化
思路与推导
  1. 凑出金额 0 不需要硬币,所以状态边界是 dp[0]=0;其他金额保持 INF 表示尚不可达。

第 40 题(单选题,3 分)

②处应填( )。

A.
x >= coin[j] && dp[x - coin[j]] != INF
B.
x > coin[j] || dp[x - coin[j]] == INF
C.
x <= coin[j] && dp[x + coin[j]] != INF
D.
dp[x] != INF

正确答案A

解析详情
答案 A转移可行条件
思路与推导
  1. 只有 x 不小于当前硬币面值时下标 x-coin[j] 才合法,并且该前驱金额必须可达,才能加入一枚硬币转移。

第 41 题(单选题,3 分)

③处应填( )。

A.
dp[x - coin[j]] < dp[x]
B.
dp[x - 1] + coin[j] < dp[x]
C.
dp[x] + 1 < dp[x - coin[j]]
D.
dp[x - coin[j]] + 1 < dp[x]

正确答案D

解析详情
答案 D最优转移比较
思路与推导
  1. 从 x-coin[j] 的最优方案加入一枚 coin[j],候选硬币数是 dp[x-coin[j]]+1;只有候选严格更小时才更新 dp[x]。

第 42 题(单选题,3 分)

④处应填( )。

A.
last[j] = x
B.
last[x] = j
C.
last[x - coin[j]] = x
D.
last[x] = coin[j]

正确答案B

解析详情
答案 B记录最后选择
思路与推导
  1. 恢复方案时程序把 last[x] 当作 coin 的下标使用,因此应记录使 dp[x] 改进的硬币下标 j。

第 43 题(单选题,3 分)

⑤处应填( )。

A.
x += coin[last[x]]
B.
x -= last[x]
C.
x -= coin[last[x]]
D.
x = last[x]

正确答案C

解析详情
答案 C沿前驱回退
思路与推导
  1. 已经输出最后使用的硬币后,剩余金额应减去该硬币面值,即 x-=coin[last[x]];由于面值为正,循环必向 0 推进。