Initial commit: C++ courseware
This commit is contained in:
commit
4a4ee7c287
1789 files changed
+373489
No files matched your search
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
+61
@@ -0,0 +1,61 @@
|
||||
### **2024 CCF 非专业级别软件能力认证第一轮 (CSP-J1) 参考答案**
|
||||
|
||||
#### **一、单项选择题**
|
||||
1. **C**
|
||||
2. **A** (原式为 $(12_{10} - 10_{10}) * 13_{10} - 13_{10} = 2 * 13 - 13 = 13$)
|
||||
3. **B** (A选2人,BC各1人: C(4,2)×C(3,1)×C(3,1)=54; B选2人,AC各1人: C(4,1)×C(3,2)×C(3,1)=36; C选2人,AB各1人: C(4,1)×C(3,1)×C(3,2)=36。总计54+36+36=126)
|
||||
4. **D** (格雷码的特性是相邻两个编码只有一位不同)
|
||||
5. **D** (1MB = 1024 * 1024 Bytes = 1024 * 1024 * 8 bits = 8388608 bits)
|
||||
6. **C** (`struct` 是构造数据类型,不是基本数据类型)
|
||||
7. **D** (`repeat-until` 是 Pascal 等语言的语法)
|
||||
8. **B** (字符'a'的ASCII码是97,97 + 13 = 110,110对应的字符是'n')
|
||||
9. **B** (2⁹ = 512, 2¹⁰ = 1024。所以最多比较10次)
|
||||
10. **A** (Notepad是记事本应用软件)
|
||||
11. **B** (图论基本定理:每条边连接两个顶点,为总度数贡献2)
|
||||
12. **A** (通过前序和中序遍历结果可以唯一确定一棵二叉树,从而得到其后序遍历)
|
||||
13. **D** (栈的特性是后进先出,可逐项模拟验证,D项无法实现)
|
||||
14. **A** (捆绑法:将3个女生视为一个整体,与5个男生进行全排列,有 `P(6,6)` 种方法。3个女生内部也有 `P(3,3)` 种排列。总数为 `6! * 3! = 720 * 6 = 4320`)
|
||||
15. **B**
|
||||
|
||||
---
|
||||
#### **二、阅读程序**
|
||||
|
||||
**(1)**
|
||||
16. **√** (10以内的质数是2, 3, 5, 7,共4个,和为17)
|
||||
17. **×** (判断逻辑依然正确,20以内的质数有8个,输出不会变为6)
|
||||
18. **√**
|
||||
19. **B** (1到50的质数之和为328)
|
||||
20. **A** (修改后,任何大于1的数 `p` 在循环到 `i=p` 时都会因 `p % p == 0` 而被误判为非质数,导致结果错误)
|
||||
|
||||
**(2)**
|
||||
21. **√** (模拟DP过程:dp[1]=10, dp[2]=min(10,0)+15=15, dp[3]=min(15,10)+20=30。返回min(dp[3], dp[2])即min(30,15)=15)
|
||||
22. **×** (不会产生编译错误,但可能会因访问数组负数下标而产生运行时错误)
|
||||
23. **×** (程序计算的是到达楼顶的最小花费路径,不一定是单个最小元素)
|
||||
24. **A** (模拟DP过程,最终返回min(dp[10], dp[9]) = min(6, 104) = 6)
|
||||
25. **B** (模拟DP过程,最终返回min(dp[7], dp[6]) = min(45, 30) = 30)
|
||||
26. **A** (修改后模拟计算:dp[1]=5, dp[2]=dp[1]+cost[0]=5+5=10, dp[3]=dp[2]+cost[1]=10+10=20。返回min(20,10)=10)
|
||||
|
||||
**(3)**
|
||||
27. **×** (`customFunction(2, 3)` 返回 8。题目问的是函数的返回值,而不是最终输出。最终输出 `pow(8, 2)` 是64)
|
||||
28. **√** (b为负数,`b-1` 永远不会等于0,导致无限递归)
|
||||
29. **√** (b越大,递归深度越大,运行时间越长)
|
||||
30. **B** (该函数计算 `a * (b + 1)`,即 `5 * (4 + 1) = 25`)
|
||||
31. **C** (`customFunction(3, 3)` 返回 `3 * (3 + 1) = 12`。程序最终输出 `pow(12, 2)` 即 144)
|
||||
32. **D** (修改后递归计算:f(3,3) = 3+f(2,2) = 3+2+f(1,1) = 3+2+1+f(0,0) = 3+2+1+0=6。最终输出`pow(6,2)`即36)
|
||||
|
||||
---
|
||||
#### **三、完善程序**
|
||||
|
||||
**(1) 判断平方数**
|
||||
33. **A** (从1开始检查)
|
||||
34. **B** (循环的上界是原数的平方根,没有必要超过它)
|
||||
35. **C** (判断`i`的平方是否等于`num`)
|
||||
36. **C** (如果找到,说明是平方数,返回`true`)
|
||||
37. **D** (如果循环结束都没找到,说明不是平方数,返回`false`)
|
||||
|
||||
**(2) 汉诺塔问题**
|
||||
38. **B** (递归的边界条件:当只剩一个盘子时,直接移动)
|
||||
39. **B** (对应 `move(src, tgt)`)
|
||||
40. **B** (第一步:将 `i-1` 个盘子从 `src` 经由 `tgt` 移到 `tmp`)
|
||||
41. **B** (第三步的盘子数量为 `i-1`)
|
||||
42. **B** (第三步:将 `i-1` 个盘子从 `tmp` 经由 `src` 移到 `tgt`)
|
||||
+348
@@ -0,0 +1,348 @@
|
||||
<center><font size="6"><b>2019 CCF 非专业级别软件能力认证第一轮</b></font></center>
|
||||
<center><font size="4"><b>(CSP-J1) 入门级 C++语言试题</b></font></center>
|
||||
<center><font size="4"><b>认证时间:2019 年 9 月 16 日 09:30~11:30</b></font></center>
|
||||
|
||||
**考生注意事项:**
|
||||
- 试题纸共有 10 页,答题纸共有 1 页,满分 100 分。请在答题纸上作答,写在试题纸上的一律无效。
|
||||
- 不得使用任何电子设备(如计算器、手机、电子词典等)或查阅任何书籍资料。
|
||||
|
||||
---
|
||||
#### **一、 单项选择题(共 15 题, 每题 2 分, 共计 30 分; 每题有且仅有一个正确选项)**
|
||||
|
||||
( ) 1. 中国的国家顶级域名是?
|
||||
A. .cn B. .ch C. .chn D. .china
|
||||
|
||||
( ) 2. 二进制数 `11101110010111` 和 `01011011101011` 进行逻辑与运算的结果是?
|
||||
A. 01001010001011
|
||||
B. 01001010010011
|
||||
C. 01001010000001
|
||||
D. 01001010000011
|
||||
|
||||
( ) 3. 一个 32 位整型变量占用多少个字节?
|
||||
A. 32 B. 128 C. 4 D. 8
|
||||
|
||||
( ) 4. 若有如下程序段,其中 s、a、b、c 均已定义为整型变量,且 a、c 均已赋值(c 大于 0)
|
||||
```cpp
|
||||
s = a;
|
||||
for (b = 1; b <= c; b++)
|
||||
s = s - 1;
|
||||
```
|
||||
则与上述程序段功能等价的赋值语句是?
|
||||
A. `s = a - c;` B. `s = a - b;`
|
||||
C. `s = s - c;` D. `s = b - c;`
|
||||
|
||||
( ) 5. 设有 100 个已排好序的数据元素,采用折半查找时,最大比较次数为?
|
||||
A. 7 B. 10 C. 6 D. 8
|
||||
|
||||
( ) 6. 链表不具有的特点是?
|
||||
A. 插入删除不需要移动元素
|
||||
B. 不必事先估计存储空间
|
||||
C. 所需空间与线性表长度成正比
|
||||
D. 可随机访问任一元素
|
||||
|
||||
( ) 7. 把 8 个同样的球放在 5 个同样的袋子里,允许有的袋子空着不放,问共有多少种不同的分法?
|
||||
提示:如果 8 个球都放在一个袋子里,无论是哪个袋子,都只算同一种分法。
|
||||
A. 22 B. 24 C. 18 D. 20
|
||||
|
||||
( ) 8. 一棵二叉树如下图所示,若采用顺序存储结构,即用一维数组元素存储该二叉树中的结点(根结点的下标为 1,若某结点的下标为 i,则其左孩子位于下标 2i 处、右孩子位于下标 2i+1 处),则该数组的最大下标至少为?
|
||||
|
||||
<center><img src="C:\Users\xiaolinquan\AppData\Roaming\Typora\typora-user-images\image-20260630210146217.png" width="15%"></center>
|
||||
|
||||
A. 6 B. 10 C. 15 D. 12
|
||||
|
||||
( ) 9. 100 以内最大的素数是?
|
||||
A. 89 B. 97 C. 91 D. 93
|
||||
|
||||
( ) 10. 319 和 377 的最大公约数是?
|
||||
A. 27 B. 33 C. 29 D. 31
|
||||
|
||||
( ) 11. 新学期开学了,小胖想减肥,健身教练给小胖制定了两个训练方案。方案一:每次连续跑 3 公里可以消耗 300 千卡(耗时半小时);方案二:每次连续跑 5 公里可以消耗 600 千卡(耗时 1 小时)。小胖每周周一到周四能抽出半小时跑步,周五到周日能抽出一小时跑步。另外,教练建议小胖每周最多跑 21 公里,否则会损伤膝盖。请问如果小胖想严格执行教练的训练方案,并且不想损伤膝盖,每周最多通过跑步消耗多少千卡?
|
||||
A. 3000 B. 2500 C. 2400 D. 2520
|
||||
|
||||
( ) 12. 一副纸牌除掉大小王有 52 张牌,四种花色,每种花色 13 张。假设从这 52 张牌中随机抽取 13 张纸牌,则至少多少张牌的花色一致。
|
||||
A. 4 B. 2 C. 3 D. 5
|
||||
|
||||
( ) 13. 一些数字可以颠倒过来看,例如 0、1、8 颠倒过来还是本身, 6 颠倒过来是 9, 9 颠倒过来看还是 6,其他数字颠倒过来都不构成数字。类似的,一些多位数也可以颠倒过来看,比如 106 颠倒过来是 901。假设某个城市的车牌只由 5 位数字组成,每一位都可以取 0 到 9。请问这个城市最多有多少个车牌倒过来恰好还是原来的车牌?
|
||||
A. 60 B. 125 C. 75 D. 100
|
||||
|
||||
( ) 14. 假设一棵二叉树的后序遍历序列为 `DGJHEBIFCA`,中序遍历序列为 `DBGEHJACIF`,则其前序遍历序列为?
|
||||
A. ABCDEFGHIJ
|
||||
B. ABDEGHJCFI
|
||||
C. ABDEGJHCFI
|
||||
D. ABDEGHJFIC
|
||||
|
||||
( ) 15. 以下哪个奖项是计算机科学领域的最高奖?
|
||||
A. 图灵奖 B. 鲁班奖 C. 诺贝尔奖 D. 普利策奖
|
||||
|
||||
---
|
||||
#### **二、阅读程序(程序输入不超过数组或字符串定义的范围:判断题正确填√,错误填×;除特殊说明外,判断题 1.5 分,选择题 3 分,共计 40 分)**
|
||||
|
||||
**(1)**
|
||||
```cpp
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
using namespace std;
|
||||
char st[100];
|
||||
int main() {
|
||||
scanf("%s", st);
|
||||
int n = strlen(st);
|
||||
for (int i = 1; i <= n; ++i) {
|
||||
if (n % i == 0) {
|
||||
char c = st[i - 1];
|
||||
if (c >= 'a')
|
||||
st[i - 1] = c - 'a' + 'A';
|
||||
}
|
||||
}
|
||||
printf("%s", st);
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
**判断题**
|
||||
( ) 1. 输入的字符串只能由小写字母或大写字母组成。
|
||||
( ) 2. 若将第 8 行的“`i=1`”改为“`i=0`”,程序运行时会发生错误。
|
||||
( ) 3. 若将第 8 行的“`i<=n`”改为“`i*i<=n`”,程序运行结果不会改变。
|
||||
( ) 4. 若输入的字符串全部由大写字母组成,那么输出的字符串就跟输入的字符串一样。
|
||||
|
||||
**选择题**
|
||||
( ) 5. 若输入的字符串长度为 18,那么输入的字符串跟输出的字符串相比,至多有多少个字符不同?
|
||||
A. 18 B. 6 C. 10 D. 1
|
||||
|
||||
( ) 6. 若输入的字符串长度为\_\_\_\_\_\_,那么输入的字符串跟输出的字符串相比,至多有36个字符不同。
|
||||
A. 36 B. 100000 C. 1 D. 128
|
||||
|
||||
**(2)**
|
||||
|
||||
```cpp
|
||||
#include <cstdio>
|
||||
using namespace std;
|
||||
int n, m;
|
||||
int a[100], b[100];
|
||||
|
||||
int main() {
|
||||
scanf("%d%d", &n, &m);
|
||||
for (int i = 1; i <= n; ++i)
|
||||
a[i] = b[i] = 0;
|
||||
for (int i = 1; i <= m; ++i) {
|
||||
int x, y;
|
||||
scanf("%d%d", &x, &y);
|
||||
if (a[x] < y && b[y] < x) {
|
||||
if (a[x] > 0)
|
||||
b[a[x]] = 0;
|
||||
if (b[y] > 0)
|
||||
a[b[y]] = 0;
|
||||
a[x] = y;
|
||||
b[y] = x;
|
||||
}
|
||||
}
|
||||
int ans = 0;
|
||||
for (int i = 1; i <= n; ++i) {
|
||||
if (a[i] == 0)
|
||||
++ans;
|
||||
if (b[i] == 0)
|
||||
++ans;
|
||||
}
|
||||
printf("%d\n", ans);
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
假设输入的 n 和 m 都是正整数,x 和 y 都是在[1,n]的范围内的整数,完成下面的判断题和单选题:
|
||||
|
||||
**判断题**
|
||||
( ) 1. 当 m>0 时,输出的值一定小于 2n。
|
||||
( ) 2. 执行完第 27 行的“`++ans`”时,ans 一定是偶数。
|
||||
( ) 3. `a[i]`和 `b[i]`不可能同时大于 0。
|
||||
( ) 4. 若程序执行到第 13 行时,x 总是小于 y,那么第 15 行不会被执行。
|
||||
|
||||
**选择题**
|
||||
( ) 5. 若 m 个 x 两两不同,且 m 个 y 两两不同,则输出的值为?
|
||||
A. 2n-2m B. 2n+2 C. 2n-2 D. 2n
|
||||
|
||||
( ) 6. 若 m 个 x 两两不同,且 m 个 y 都相等,则输出的值为?
|
||||
A. 2n-2 B. 2n C. 2m D. 2n-2m
|
||||
|
||||
**(3)**
|
||||
|
||||
```cpp
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
const int maxn = 10000;
|
||||
int n;
|
||||
int a[maxn];
|
||||
int b[maxn];
|
||||
int f(int l, int r, int depth) {
|
||||
if (l > r)
|
||||
return 0;
|
||||
int min_val = maxn, mink;
|
||||
for (int i = l; i <= r; ++i) {
|
||||
if (min_val > a[i]) {
|
||||
min_val = a[i];
|
||||
mink = i;
|
||||
}
|
||||
}
|
||||
int lres = f(l, mink - 1, depth + 1);
|
||||
int rres = f(mink + 1, r, depth + 1);
|
||||
return lres + rres + depth * b[mink];
|
||||
}
|
||||
int main() {
|
||||
cin >> n;
|
||||
for (int i = 0; i < n; ++i)
|
||||
cin >> a[i];
|
||||
for (int i = 0; i < n; ++i)
|
||||
cin >> b[i];
|
||||
cout << f(0, n - 1, 1) << endl;
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
**判断题**
|
||||
( ) 1. 如果 a 数组有重复的数字,则程序运行时会发生错误。
|
||||
( ) 2. 如果 b 数组全为 0,则输出为 0。
|
||||
|
||||
**选择题**
|
||||
( ) 3. 当 n=100 时,最坏情况下,与第 12 行的比较运算执行的次数最接近的是?
|
||||
A. 5000 B. 600 C. 6 D. 100
|
||||
|
||||
( ) 4. 当 n=100 时,最好情况下,与第 12 行的比较运算执行的次数最接近的是?
|
||||
A. 100 B. 6 C. 5000 D. 600
|
||||
|
||||
( ) 5. 当 n=10 时,若 b 数组满足,对任意 0≤i<n,都有 b[i]=i+1,那么输出最大为?
|
||||
A. 386 B. 383 C. 384 D. 385
|
||||
|
||||
( ) 6. (4 分)当 n=100 时,若 b 数组满足,对任意 0≤i<n,都有 b[i]=1,那么输出最小为?
|
||||
A. 582 B. 580 C. 579 D. 581
|
||||
|
||||
---
|
||||
#### **三、完善程序(单选题,每小题 3 分,共计 30 分)**
|
||||
|
||||
**(1) (矩阵变幻)** 有一个奇幻的矩阵,在不停地变幻,其变幻方式为:数字 0 变成矩阵 $\begin{bmatrix} 0 & 0 \\ 0 & 1 \end{bmatrix}$,数字 1 变成矩阵 $\begin{bmatrix} 1 & 1 \\ 1 & 0 \end{bmatrix}$。最初该矩阵只有一个元素 0,变幻n 次后,矩阵会变成什么样?
|
||||
输入一行一个不超过 10 的正整数 n。输出变幻 n 次后的矩阵。试补全程序。
|
||||
|
||||
提示:“`<<`”表示二进制左移运算符;“`^`”表示二进制异或运算符。
|
||||
|
||||
```cpp
|
||||
#include <cstdio>
|
||||
using namespace std;
|
||||
int n;
|
||||
const int max_size = 1 << 10;
|
||||
int res[max_size][max_size];
|
||||
|
||||
void recursive(int x, int y, int n, int t) {
|
||||
if (n == 0) {
|
||||
res[x][y] = __(1)__;
|
||||
return;
|
||||
}
|
||||
int step = 1 << (n - 1);
|
||||
recursive(__(2)__, n - 1, t);
|
||||
recursive(x, y + step, n - 1, t);
|
||||
recursive(x + step, y, n - 1, t);
|
||||
recursive(__(3)__, n - 1, !t);
|
||||
}
|
||||
|
||||
int main() {
|
||||
scanf("%d", &n);
|
||||
recursive(0, 0, __(4)__);
|
||||
int size = __(5)__;
|
||||
for (int i = 0; i < size; i++) {
|
||||
for (int j = 0; j < size; j++)
|
||||
printf("%d ", res[i][j]);
|
||||
puts("");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
( ) 1. ①处应填
|
||||
A. `n % 2` B. `0` C. `t` D. `1`
|
||||
|
||||
( ) 2. ②处应填
|
||||
A. `x - step, y - step`
|
||||
B. `x, y - step`
|
||||
C. `x - step, y`
|
||||
D. `x, y`
|
||||
|
||||
( ) 3. ③处应填
|
||||
A. `x - step, y - step`
|
||||
B. `x + step, y + step`
|
||||
C. `x - step, y`
|
||||
D. `x, y - step`
|
||||
|
||||
( ) 4. ④处应填
|
||||
A. `n - 1, n % 2`
|
||||
B. `n, 0`
|
||||
C. `n, n % 2`
|
||||
D. `n - 1, 0`
|
||||
|
||||
( ) 5. ⑤处应填
|
||||
A. `1 << (n + 1)`
|
||||
B. `1 << n`
|
||||
C. `n + 1`
|
||||
D. `1 << (n - 1)`
|
||||
|
||||
**(2) (计数排序)** 计数排序是一个广泛使用的排序方法。下面的程序使用双关键字计数排序,对 n 对 10000 以内的整数,从小到大排序。
|
||||
例如有三对整数 (3, 4), (2, 4), (3, 3),那么排序之后应该是 (2, 4), (3, 3), (3, 4)。
|
||||
输入第一行为 n,接下来 n 行,第 i 行有两个数 a[i] 和 b[i],分别表示第 i 对整数的第一关键字和第二关键字。
|
||||
|
||||
提示:应先对第二关键字排序,再对第一关键字排序。数组 `ord[]` 存储第二关键字排序的结果,数组 `res[]` 存储双关键字排序的结果。
|
||||
|
||||
```cpp
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
using namespace std;
|
||||
const int maxn = 10000000;
|
||||
const int maxs = 10000;
|
||||
|
||||
int n;
|
||||
unsigned a[maxn], b[maxn], res[maxn], ord[maxn];
|
||||
unsigned cnt[maxs + 1];
|
||||
|
||||
int main() {
|
||||
scanf("%d", &n);
|
||||
for (int i = 0; i < n; ++i)
|
||||
scanf("%u%u", &a[i], &b[i]);
|
||||
memset(cnt, 0, sizeof(cnt));
|
||||
for (int i = 0; i < n; ++i)
|
||||
__(1)__; // 利用 cnt 数组统计数量
|
||||
for (int i = 1; i <= maxs; ++i)
|
||||
cnt[i] += cnt[i - 1];
|
||||
for (int i = n - 1; i >= 0; --i)
|
||||
__(2)__; // 记录初步排序结果
|
||||
memset(cnt, 0, sizeof(cnt));
|
||||
for (int i = 0; i < n; ++i)
|
||||
__(3)__; // 利用 cnt 数组统计数量
|
||||
for (int i = 1; i <= maxs; ++i)
|
||||
cnt[i] += cnt[i - 1];
|
||||
for (int i = n - 1; i >= 0; --i)
|
||||
__(4)__; // 记录最终排序结果
|
||||
for (int i = 0; i < n; i++)
|
||||
printf("%u %u\n", ⑤);
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
( ) 1. ① 处应填
|
||||
A. `++cnt[i]`
|
||||
B. `++cnt[b[i]]`
|
||||
C. `++cnt[a[i] * maxs + b[i]]`
|
||||
D. `++cnt[a[i]]`
|
||||
|
||||
( ) 2. ② 处应填
|
||||
A. `ord[--cnt[a[i]]] = i`
|
||||
B. `ord[--cnt[b[i]]] = a[i]`
|
||||
C. `ord[--cnt[a[i]]] = b[i]`
|
||||
D. `ord[--cnt[b[i]]] = i`
|
||||
|
||||
( ) 3. ③ 处应填
|
||||
A. `++cnt[b[ord[i]]]`
|
||||
B. `++cnt[a[i] * maxs + b[i]]`
|
||||
C. `++cnt[a[ord[i]]]`
|
||||
D. `++cnt[i]`
|
||||
|
||||
( ) 4. ④ 处应填
|
||||
A. `res[--cnt[a[ord[i]]]] = ord[i]`
|
||||
B. `res[--cnt[b[ord[i]]]] = ord[i]`
|
||||
C. `res[--cnt[b[i]]] = ord[i]`
|
||||
D. `res[--cnt[a[i]]] = ord[i]`
|
||||
|
||||
( ) 5. ⑤处应填
|
||||
A. `a[i], b[i]`
|
||||
B. `a[res[i]], b[res[i]]`
|
||||
C. `a[ord[res[i]]], b[ord[res[i]]]`
|
||||
D. `a[res[ord[i]]], b[res[ord[i]]]`
|
||||
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
+113
@@ -0,0 +1,113 @@
|
||||
### 一、单项选择题
|
||||
**1. A**
|
||||
**解析**:`printf` 是 C 语言标准库中的函数,属于面向过程的特性。而类的封装、继承(基类与派生类)和成员函数均是 C++ 的面向对象特性。
|
||||
|
||||
**2. C**
|
||||
**解析**:对于选项 C(3 4 6 5 2 1),进栈顺序必然为 6, 5, 4, 3。此时栈内元素为 6, 5, 4, 3(3在栈顶)。弹出 3 和 4 后,栈顶元素为 5。要想弹出 6,必须先弹出 5,因此 6 不可能在 5 之前出栈,该序列非法。
|
||||
|
||||
**3. D**
|
||||
**解析**:`p` 和 `q` 是指针变量,分别保存 `x` 和 `y` 的地址。`p = q` 将 `q` 的值(即 `y` 的地址)赋给 `p`,因此 `p` 指向了 `y` 的地址。
|
||||
|
||||
**4. C**
|
||||
**解析**:数组和链表都可以排序;它们存储信息的量取决于内存,没有绝对的“谁能存更多”;数组在普通声明时大小是固定的(静态分配),而链表可以通过动态内存分配随时调整大小。
|
||||
|
||||
**5. B**
|
||||
**解析**:根据队列 Q 的出队顺序(e2, e4, e3, e6, e5, e1),这也是它们进入队列 Q 的顺序,同时也是它们从栈 S 出栈的顺序。模拟栈 S 的操作:
|
||||
- e1 进栈 (S: e1)
|
||||
- e2 进栈 (S: e1, e2) -> e2 出栈 (S: e1)
|
||||
- e3 进栈 (S: e1, e3)
|
||||
- e4 进栈 (S: e1, e3, e4) -> e4 出栈 (S: e1, e3) -> e3 出栈 (S: e1)
|
||||
- e5 进栈 (S: e1, e5)
|
||||
- e6 进栈 (S: e1, e5, e6) -> e6 出栈 (S: e1, e5) -> e5 出栈 (S: e1) -> e1 出栈 (S: 空)
|
||||
在此过程中,栈 S 同时容纳的最多元素个数为 3。
|
||||
|
||||
**6. B**
|
||||
**解析**:前缀表达式(波兰式)将操作符放在操作数前面。`a+(b-c)*d` 对应的语法树根节点是 `+`,左子树是 `a`,右子树是 `*`。转化为前缀表达式为 `+ a * - b c d`。
|
||||
|
||||
**7. B**
|
||||
**解析**:构造哈夫曼树:10(a)和15(b)合并为25;16(d)和25合并为41;29(e)和30(c)合并为59;41和59合并为100(根)。字母 d (16) 位于根结点的左子树的左子树,深度为 2,故编码长度为 2。
|
||||
|
||||
**8. C**
|
||||
**解析**:完全二叉树中,节点 `i` 的父节点为 `i/2`,左子节点为 `2i`,右子节点为 `2i+1`。节点 9 的父节点为 4,4 的左子节点是 8,所以 9 的兄弟节点是 8。节点 9 的右子节点为 `2*9+1 = 19`。
|
||||
|
||||
**9. B**
|
||||
**解析**:要使有向图连通(在图论强连通语境下),最少需要形成一个环,即 N 个顶点至少需要 N 条有向边。因此邻接矩阵中至少存在 N 个非零元素。
|
||||
|
||||
**10. D**
|
||||
**解析**:栈和队列可以通过互相模拟来实现。例如,使用两个栈可以实现一个队列的操作。D选项错误。
|
||||
|
||||
**11. D**
|
||||
**解析**:在双向循环链表中 `p` 后插入 `s`,需要四步操作,顺序需保证未更新的指针不丢失:
|
||||
1. `s->next = p->next;`
|
||||
2. `p->next->prev = s;` (或 `s->next->prev = s;`)
|
||||
3. `s->prev = p;`
|
||||
4. `p->next = s;`
|
||||
|
||||
**12. B**
|
||||
**解析**:简单选择排序是不稳定的。例如序列 [2, 2*, 1],第一轮选择最小的 1 与第一个 2 交换,变成 [1, 2*, 2],两个 2 的相对顺序发生了改变。
|
||||
|
||||
**13. C**
|
||||
**解析**:八进制数 $(32.1)_8$ = $3 \times 8^1 + 2 \times 8^0 + 1 \times 8^{-1}$ = $24 + 2 + 0.125 = 26.125$。
|
||||
|
||||
**14. B**
|
||||
**解析**:字符串 `abcab` 的子串有:长度为1的 a,b,c(3);长度为2的 ab,bc,ca(3);长度为3的 abc,bca,cab(3);长度为4的 abca,bcab(2);长度为5的 abcab(1);还有1个空串,合计 13 个内容互不相同的子串。
|
||||
|
||||
**15. B**
|
||||
**解析**:递归的基本定义就是函数直接或间接地调用自身来解决问题。
|
||||
|
||||
---
|
||||
|
||||
### 二、阅读程序
|
||||
|
||||
**(1) 位运算(Morton Code 交错)**
|
||||
*程序分析:该程序利用位运算将 `x` 和 `y` 的二进制位交错插入,实现空间降维(Z-order curve)。*
|
||||
|
||||
**16. √**:去掉 `unsigned` 后,变量变为有符号 `short`。由于输入均是不超过 15(`1111`)的非负数,进行左移和按位与运算时始终在低 8 位操作,符号位不受影响,结果不变。
|
||||
**17. ×**:若改为 `char`,最后 `z` 也是 `char` 类型。当使用 `cout << z` 输出时,C++ 会将 `char` 作为**字符**(ASCII)输出,而不是输出对应的整数数字,导致输出行为发生巨大改变。
|
||||
**18. ×**:如 x=1, y=1 时,输出显然不为 0。
|
||||
**19. ×**:输入 `2 2`,此时 `x=2(0010)`,交错后 `x=4(0100)`;同理 `y=4(0100)`。`z = 4 | (4 << 1) = 4 | 8 = 12`,并非 10。
|
||||
**20. ×**:计算同上,输出为 12。
|
||||
**21. B**:当输入 `13 8` 时:13 二进制是 `1101`,展开后为 `01010001`,即 `x=81`;8 二进制是 `1000`,展开后为 `01000000`,即 `y=64`。`y<<1 = 128`,`z = 81 | 128 = 209`。
|
||||
|
||||
**(2) 动态规划(扔鸡蛋问题)**
|
||||
*程序分析:这是经典的扔鸡蛋问题。`f` 是递归求解,`g` 是对应的 DP 递推求解。*
|
||||
|
||||
**22. ×**:利用递归树递推其函数调用次数:执行 `min` 的次数等于 `for` 循环迭代总次数。计算得出 $C(7, 3) = 448$ 次,而不是 449 次。
|
||||
**23. √**:两个函数实现完全等价的状态转移方程,一个为纯递归,另一个为自底向上的动态规划,所以在不考虑超时的理论情况下,两者输出结果恒等。
|
||||
**24. √**:观察代码 `if (m == 1) return n;`,当 m 为 1 时,函数直接返回 n。
|
||||
**25. C**:`g(n, m)` 有三层 `for` 循环:第一层到 $n$,第二层到 $m$,第三层到 $i$ (即受限于 $n$)。时间复杂度为 $O(n \times m \times n) = O(n^2m)$。
|
||||
**26. C**:输入 `20 2`,表示 2 个鸡蛋测 20 层楼。公式为求满足 $k(k+1)/2 \ge 20$ 的最小 $k$。当 $k=6$ 时,得 21,满足条件,因此答案为 6。
|
||||
**27. B**:鸡蛋数 $m=100$ 足以覆盖楼层数 $n=100$ 的二分查找消耗。只需执行标准的二分查找,最坏情况需 $\lceil \log_2(101) \rceil = 7$ 次。
|
||||
|
||||
**(3) 二分查找与牛顿迭代法求平方根**
|
||||
*程序分析:`solve1` 通过二分查找求 $\lfloor \sqrt{n} \rfloor$;`solve2` 通过牛顿迭代法逼近精确的 $\sqrt{n}$。*
|
||||
|
||||
**28. √**:`solve1` 的 `while` 循环折半查找需要 $O(\log n)$,`solve2` 进行 `k` 次循环需要 $O(k)$,总时间复杂度为 $O(\log n + k)$。
|
||||
**29. √**:9801 是 99 的平方,`solve1` 返回 99,`solve2` 第一轮迭代公式 $x = (99 + 9801/99)/2 = 99$,故直接输出 99。
|
||||
**30. ×**:C++ 中浮点数 `double` 存在精度限制。对于非完全平方数,无论迭代多少次,`ans * ans` 由于精度丢失,难以做到在二进制浮点下与原整数 `n` 绝对全等(`==` 通常为 `false`)。
|
||||
**31. ×**:输入 $n$ 最大为 47000。此时 `mid` 最大约 23500。`mid * mid` 最大为 $23500^2 = 552,250,000$。该值远小于 32 位带符号整型上限 $2^{31}-1 = 2,147,483,647$,不会发生溢出。
|
||||
**32. C**:$n=2, k=1$。`solve1(2)` 返回 1。`solve2` 迭代一次:$x = (1 + 2/1) / 2 = 1.5$。
|
||||
**33. B**:牛顿迭代法收敛极快,经过 10 次迭代,求出的解高度逼近于 $\sqrt{3}$,其值为 1.73205...。
|
||||
**34. A**:$n=256, k=11$。256 为 16 的平方,`solve1` 准确返回 16。带入 `solve2` 每次迭代结果均为 16 本身,等于 16。
|
||||
|
||||
---
|
||||
|
||||
### 三、完善程序
|
||||
|
||||
**(1) 枚举因数**
|
||||
*寻找 `n` 所有的正因数。先找出所有 $<\sqrt{n}$ 的因数存入数组 `fac`,然后输出,再判断是否有 $\sqrt{n}$ 这个特定因数,最后倒序输出 $> \sqrt{n}$ 的配对因数。*
|
||||
|
||||
**35. A**:判断 `i` 是否是 `n` 的因数,条件为 `n % i == 0`。
|
||||
**36. B**:首先顺序输出前半部分的因数,保存在 `fac` 数组中,故直接输出 `fac[k]`。
|
||||
**37. C**:判断完全平方数的情况,即当 `i` 的平方刚好等于 `n` 时,`i` 就是处于中间的那一个因数(比如 `n=9` 时的 `3`),条件为 `i * i == n`。
|
||||
**38. D**:若成立,需要单独输出该平方根因数,即 `i`。
|
||||
**39. A**:最后通过逆序遍历 `fac` 数组,输出与之配对的较大的因数,即 `n / fac[k]`。
|
||||
|
||||
**(2) 洪水填充**
|
||||
*经典的 BFS (广度优先搜索) 算法应用,在 8x8 棋盘上做颜色的联通块覆盖。*
|
||||
|
||||
**40. A**:入队前检查当前遍历到的像素,它必须在未修改之前与原中心点的颜色保持一致,所以 `image[r][c] == prev_color`。
|
||||
**41. B**:找到起始点 `cur` 后,应立刻将其颜色标记修改为给定的新颜色 `new_color`,避免以后重复入队。`image[cur.r][cur.c] = new_color`。
|
||||
**42. C**:定义 `points[4]` 分别表示上下左右四个邻居。现给出了上 `r-1`、右 `c+1`、左 `c-1`,缺失的那个自然是下方的坐标,即 `Point(pt.r + 1, pt.c)`。
|
||||
**43. D**:在寻找到满足拓展条件的邻居点 `p` 时,需将其染色以作为已访问的标记:`image[p.r][p.c] = new_color`。
|
||||
**44. A**:染色完毕后,将该符合条件的邻居节点 `p` 压入队列,以进行下一步的外层搜索扩展,即 `queue.push(p)`。
|
||||
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
+472
@@ -0,0 +1,472 @@
|
||||
<center><font size="6"><b>2023 CCF 非专业级别软件能力认证第一轮</b></font></center>
|
||||
<center><font size="4"><b>(CSP-S1) 提高级 C++语言试题</b></font></center>
|
||||
<center><font size="4"><b>认证时间:2023年9月16日 14:30~16:30</b></font></center>
|
||||
|
||||
**考生注意事项:**
|
||||
- 试题纸共有13 页,答题纸共有1页,满分 100 分。请在答题纸上作答,写在试题纸上的一律无效。
|
||||
- 不得使用任何电子设备(如计算器、手机、电子词典等)或查阅任何书籍资料。
|
||||
|
||||
---
|
||||
#### **一、单项选择题(共15题,每题2分,共计 30分:每题有且仅有一个正确选项)**
|
||||
|
||||
( ) 1. 在 Linux 系统终端中,以下哪个命令用于创建一个新的目录?
|
||||
A. newdir
|
||||
B. mkdir
|
||||
C. create
|
||||
D. mkfolder
|
||||
|
||||
( ) 2. 0, 1, 2, 3, 4中选取4个数字,能组成多少个不同四位数。(注:最小的四位数是1000, 最大的四位数是9999。)
|
||||
A. 96
|
||||
B. 18
|
||||
C. 120
|
||||
D. 84
|
||||
|
||||
( ) 3. 假设n是图的顶点的个数,m是图的边的个数,为求解某一问题有下面四种不同时间复杂度的算法。对于m = O(n)的稀疏图而言,下面的四个选项,哪一项的渐近时间复杂度最小。
|
||||
A. O(m log n / log log n)
|
||||
B. O(n² + m)
|
||||
C. O(n²/log m + m log n)
|
||||
D. O(m + n log n)
|
||||
|
||||
( ) 4. 假设有n根柱子,需要按照以下规则依次放置编号为1、2、3、……的圆环:每根柱子的底部固定,顶部可以放入圆环;每次从柱子顶部放入圆环时,需要保证任何两个相邻圆环的编号之和是一个完全平方数。请计算当有4根柱子时,最多可以放置多少个圆环。
|
||||
A. 7
|
||||
B. 9
|
||||
C. 11
|
||||
D. 5
|
||||
|
||||
( ) 5. 以下对数据结构的表述不恰当的一项是:( )。
|
||||
A. 队列是一种先进先出(FIFO)的线性结构
|
||||
B. 哈夫曼树的构造过程主要是为了实现图的深度优先搜索
|
||||
C. 散列表是一种通过散列函数将关键字映射到存储位置的数据结构
|
||||
D. 二叉树是一种每个结点最多有两个子结点的树结构
|
||||
|
||||
( ) 6. 以下连通无向图中,( )一定可以用不超过两种颜色进行染色。
|
||||
A. 完全三叉树
|
||||
B. 平面图
|
||||
C. 边双连通图
|
||||
D. 欧拉图
|
||||
|
||||
( ) 7. 最长公共子序列长度常常用来衡量两个序列的相似度。其定义如下:给定两个序列X= {x₁, x₂, ..., xₘ}和Y = {y₁, y₂, ..., yₙ},最长公共子序列(LCS)问题的目标是找到一个最长的新序列 Z = {z₁, z₂, ..., zₖ},使得序列Z既是序列X的子序列,又是序列Y的子序列,且序列Z的长度k在满足上述条件的序列里是最大的。则序列“ABCAAAABA”和“ABABCBABA”的最长公共子序列长度为()。
|
||||
A. 4
|
||||
B. 5
|
||||
C. 6
|
||||
D. 7
|
||||
|
||||
( ) 8. 一位玩家正在玩一个特殊的掷骰子的游戏,游戏要求连续掷两次骰子,收益规则如下:玩家第一次掷出点x,得到 2x 元;第二次掷出y点,当y=x 时玩家会失去之前得到的2x 元, 而当 y≠x 时玩家能保住第一次获得的 2x 元。上述x,y∈{1,2,3,4,5,6}。假设骰子出任意一点的概率均为1/6,玩家连续掷两次骰子后,所有可能情形下收益的平均值是多少?
|
||||
A. 7元
|
||||
B. 35/6元
|
||||
C. 6元
|
||||
D. 49/6元
|
||||
|
||||
( ) 9. 假设我们有以下的C++代码:
|
||||
```cpp
|
||||
int a = 5, b = 3, c = 4;
|
||||
bool res = a & b || c ^ b && a | c;
|
||||
```
|
||||
请问,`res` 的值是什么?()
|
||||
> 提示:在C++中,逻辑运算的优先级从高到低依次为:逻辑非(!)、逻辑与(&&)、逻辑或(||)。位运算的优先级从高到低依次为:位非(~)、位与(&)、位异或(^)、位或(|)。同时,双目位运算的优先级高于双目逻辑运算;逻辑非和位非优先级相同,且高于所有双目运算符。
|
||||
A. true
|
||||
B. false
|
||||
C. 1
|
||||
D. 0
|
||||
|
||||
( ) 10. 假设快速排序算法的输入是一个长度为n的已排序数组,且该快速排序算法在分治过程总是选择第一个元素作为基准元素。以下哪个选项描述的是在这种情况下的快速排序行为?()
|
||||
A. 快速排序对于此类输入的表现最好,因为数组已经排序。
|
||||
B. 快速排序对于此类输入的时间复杂度是 O(n log n)。
|
||||
C. 快速排序对于此类输入的时间复杂度是 O(n²)。
|
||||
D. 快速排序无法对此类数组进行排序,因为数组已经排序。
|
||||
|
||||
( ) 11. 以下哪个命令,能将一个名为“main.cpp”的C++源文件,编译并生成一个名为“main”的可执行文件?
|
||||
A. `g++ -o main main.cpp`
|
||||
B. `g++ -o main.cpp main`
|
||||
C. `g++ main -o main.cpp`
|
||||
D. `g++ main.cpp -o main.cpp`
|
||||
|
||||
( ) 12. 在图论中,树的重心是树上的一个结点,以该结点为根时,使得其所有的子树中结点数最多的子树的结点数最少。一棵树可能有多个重心。请问下面哪种树一定只有一个重心?
|
||||
A. 4个结点的树
|
||||
B. 6个结点的树
|
||||
C. 7个结点的树
|
||||
D. 8个结点的树
|
||||
|
||||
( ) 13. 如图是一张包含6个顶点的有向图,但顶点间不存在拓扑序。如果要删除其中一条边,使这6个顶点能进行拓扑排序,请问总共有多少条边可以作为候选的被删除边?( )
|
||||

|
||||
A. 1
|
||||
B. 2
|
||||
C. 3
|
||||
D. 4
|
||||
|
||||
( ) 14. 
|
||||
A. 10
|
||||
B. 11
|
||||
C. 12
|
||||
D. 13
|
||||
|
||||
( ) 15. 现在用如下代码来计算xⁿ,其时间复杂度为()。
|
||||
```cpp
|
||||
double quick_power(double x, unsigned n) {
|
||||
if (n == 0) return 1;
|
||||
if (n == 1) return x;
|
||||
return quick_power(x, n / 2)
|
||||
* quick_power(x, n / 2)
|
||||
* ((n & 1) ? x : 1);
|
||||
}
|
||||
```
|
||||
A. O(n)
|
||||
B. O(1)
|
||||
C. O(log n)
|
||||
D. O(n log n)
|
||||
|
||||
---
|
||||
#### **二、阅读程序(程序输入不超过数组或字符串定义的范围:判断题正确填√,错误填×;除特殊说明外,判断题1.5分,选择题3分,共计40分)**
|
||||
|
||||
**(1)**
|
||||
```cpp
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
unsigned short f(unsigned short x) {
|
||||
x ^= x << 6;
|
||||
x ^= x >> 8;
|
||||
return x;
|
||||
}
|
||||
|
||||
int main() {
|
||||
unsigned short x;
|
||||
cin >> x;
|
||||
unsigned short y = f(x);
|
||||
cout << y << endl;
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
假设输入的x是不超过65535 的自然数,完成下面的判断题和单选题。
|
||||
|
||||
**判断题**
|
||||
( ) 16. 当输入非零时,输出一定不为零。
|
||||
( ) 17. (2 分)将f函数的输入参数的类型改为unsigned int,程序的输出不变。
|
||||
( ) 18. 当输入为“65535”时,输出为“63”。
|
||||
( ) 19. 当输入为“1”时,输出为“64”。
|
||||
|
||||
**单选题**
|
||||
( ) 20. 当输入为“512”时,输出为()。
|
||||
A. "33280"
|
||||
B. "33410"
|
||||
C. "33106"
|
||||
D. "33346"
|
||||
|
||||
( ) 21. 当输入为“64”时,执行完第5行后x的值为( )。
|
||||
A. "8256"
|
||||
B. "4130"
|
||||
C. "4128"
|
||||
D. "4160"
|
||||
|
||||
**(2)**
|
||||
```cpp
|
||||
#include <iostream>
|
||||
#include <cmath>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
using namespace std;
|
||||
|
||||
long long solve1(int n) {
|
||||
vector<bool> p(n + 1, true);
|
||||
vector<long long> f(n + 1, 0), g(n + 1, 0);
|
||||
f[1] = 1;
|
||||
for (int i = 2; i * i <= n; i++) {
|
||||
if (p[i]) {
|
||||
vector<int> d;
|
||||
for (long long k = i; k <= n; k *= i) d.push_back(k); // 译者注:k类型应为long long
|
||||
reverse(d.begin(), d.end());
|
||||
for (int k : d) {
|
||||
for (int j = k; j <= n; j += k) {
|
||||
if (p[j]) {
|
||||
p[j] = false;
|
||||
f[j] = i;
|
||||
g[j] = k;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int i = sqrt(n) + 1; i <= n; i++) {
|
||||
if (p[i]) {
|
||||
f[i] = i;
|
||||
g[i] = i;
|
||||
}
|
||||
}
|
||||
long long sum = 1;
|
||||
for (int i = 2; i <= n; i++) {
|
||||
f[i] = f[i / g[i]] * (g[i] * f[i] - 1) / (f[i] - 1);
|
||||
sum += f[i];
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
long long solve2(int n) {
|
||||
long long sum = 0;
|
||||
for (int i = 1; i <= n; i++) {
|
||||
sum += i * (n / i);
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
int main() {
|
||||
int n;
|
||||
cin >> n;
|
||||
cout << solve1(n) << endl;
|
||||
cout << solve2(n) << endl;
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
假设输入的n是不超过1000000 的自然数,完成下面的判断题和单选题:
|
||||
|
||||
**判断题**
|
||||
( ) 22. 将第15 行删去,输出不变。
|
||||
( ) 23. 当输入为“10”时,输出的第一行大于第二行。
|
||||
( ) 24. (2分)当输入为“1000”时,输出的第一行与第二行相等。
|
||||
|
||||
**单选题**
|
||||
( ) 25. `solve1(n)`的时间复杂度为( )。
|
||||
A. O(n log² n)
|
||||
B. O(n)
|
||||
C. O(n log n)
|
||||
D. O(n log log n)
|
||||
|
||||
( ) 26. `solve2(n)`的时间复杂度为( )。
|
||||
A. O(n²)
|
||||
B. O(n)
|
||||
C. O(n log n)
|
||||
D. O(n√n)
|
||||
|
||||
( ) 27. 输入为“5”时,输出的第二行为( )
|
||||
A. "20"
|
||||
B. "21"
|
||||
C. "22"
|
||||
D. "23"
|
||||
|
||||
**(3)**
|
||||
```cpp
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
bool f0(vector<int>& a, int m, int k) {
|
||||
int s = 0;
|
||||
for (int i = 0, j = 0; i < a.size(); i++) {
|
||||
while (a[i] - a[j] > m) j++;
|
||||
s += i - j;
|
||||
}
|
||||
return s >= k;
|
||||
}
|
||||
|
||||
int f(vector<int>& a, int k) {
|
||||
sort(a.begin(), a.end());
|
||||
int g = 0;
|
||||
int h = a.back() - a[0];
|
||||
while (g < h) {
|
||||
int m = g + (h - g) / 2;
|
||||
if (f0(a, m, k)) {
|
||||
h = m;
|
||||
} else {
|
||||
g = m + 1;
|
||||
}
|
||||
}
|
||||
return g;
|
||||
}
|
||||
|
||||
int main() {
|
||||
int n, k;
|
||||
cin >> n >> k;
|
||||
vector<int> a(n, 0);
|
||||
for (int i = 0; i < n; i++) {
|
||||
cin >> a[i];
|
||||
}
|
||||
cout << f(a, k) << endl;
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
假设输入总是合法的且 |a[i]| ≤ 10⁹, n ≤ 100000 和 1 ≤ k ≤ n(n-1)/2,完成下面的判断题和单选题:
|
||||
|
||||
**判断题**
|
||||
( ) 28. 将第24 行的“m”改为“m - 1”,输出有可能不变,而剩下情况为少1。
|
||||
( ) 29. 将第22 行的“`g + (h - g) / 2`”改为“`(h + g) >> 1`", 输出不变。
|
||||
( ) 30. 当输入为“5 7 2 -4 5 1 -3”,输出为“5”。
|
||||
|
||||
**单选题**
|
||||
( ) 31. 设数组中最大值减最小值加1 为A,则f函数的时间复杂度为()。
|
||||
A. O(n log A)
|
||||
B. O(n² log A)
|
||||
C. O(n log (nA))
|
||||
D. O(n log n)
|
||||
|
||||
( ) 32. 将第 10 行中的“>”替换为“>=”,那么原输出与现输出的大小关系为()。
|
||||
A. 一定小于
|
||||
B. 一定小于等于且不一定小于
|
||||
C. 一定大于等于且不一定大于
|
||||
D. 以上三种情况都不对
|
||||
|
||||
( ) 33. 当输入为“5 8 2 -5 3 8 -12”时,输出为()。
|
||||
A. "13"
|
||||
B. "14"
|
||||
C. "8"
|
||||
D. "15"
|
||||
|
||||
---
|
||||
#### **三、完善程序(单选题,每小题3分,共计 30分)**
|
||||
|
||||
**(1) (第k 小路径)** 给定一张 n 个点 m 条边的有向无环图,顶点编号从 0 到 n-1。对于一条路径,我们定义“路径序列”为该路径从起点出发依次经过的顶点编号构成的序列。求所有至少包含一个点的简单路径中,“路径序列”字典序第k 小的路径。保证存在至少k 条路径。上述参数满足 1 ≤ n, m ≤ 10⁵ 和 1 ≤ k ≤ 10¹⁸。
|
||||
在程序中,我们求出从每个点出发的路径数量。超过10¹⁸的数都用 10¹⁸ 表示。然后我们根据 k 的值和每个顶点的路径数量,确定路径的起点,然后可以类似地依次求出路径中的每个点。试补全程序。
|
||||
```cpp
|
||||
#include <iostream>
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
|
||||
const int MAXN = 100000;
|
||||
const long long LIM = 1000000000000000001LL;
|
||||
|
||||
int n, m, deg[MAXN];
|
||||
std::vector<int> E[MAXN];
|
||||
long long k, f[MAXN];
|
||||
|
||||
int next(std::vector<int> cand, long long &k) {
|
||||
std::sort(cand.begin(), cand.end());
|
||||
for (int u : cand) {
|
||||
if (①) return u;
|
||||
k -= f[u];
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int main() {
|
||||
std::cin >> n >> m >> k;
|
||||
for (int i = 0; i < m; ++i) {
|
||||
int u, v;
|
||||
std::cin >> u >> v; // 一条从u到v的边
|
||||
E[u].push_back(v);
|
||||
++deg[v];
|
||||
}
|
||||
std::vector<int> Q;
|
||||
for (int i = 0; i < n; ++i)
|
||||
if (!deg[i]) Q.push_back(i);
|
||||
for (int i = 0; i < n; ++i) { // 译者注:此处应为 i < Q.size()
|
||||
int u = Q[i];
|
||||
for (int v : E[u]) {
|
||||
--deg[v];
|
||||
if (②) Q.push_back(v);
|
||||
}
|
||||
}
|
||||
std::reverse(Q.begin(), Q.end());
|
||||
for (int u : Q) {
|
||||
f[u] = 1;
|
||||
for (int v : E[u]) f[u] = ③;
|
||||
}
|
||||
int u = next(Q, k);
|
||||
std::cout << u << std::endl;
|
||||
while (④) {
|
||||
⑤;
|
||||
u = next(E[u], k);
|
||||
std::cout << u << std::endl;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
( ) 34. ①处应填
|
||||
A. `k >= f[u]`
|
||||
B. `k <= f[u]`
|
||||
C. `k > f[u]`
|
||||
D. `k < f[u]`
|
||||
|
||||
( ) 35. ②处应填
|
||||
A. `deg[v] == 1`
|
||||
B. `deg[v] == 0`
|
||||
C. `deg[v] > 1`
|
||||
D. `deg[v] > 0`
|
||||
|
||||
( ) 36. ③处应填
|
||||
A. `std::min(f[u] + f[v], LIM)`
|
||||
B. `std::min(f[u] + f[v] + 1, LIM)`
|
||||
C. `std::min(f[u] * f[v], LIM)`
|
||||
D. `std::min(f[u] * (f[v] + 1), LIM)`
|
||||
|
||||
( ) 37. ④处应填
|
||||
A. `u != -1`
|
||||
B. `!E[u].empty()`
|
||||
C. `k > 0`
|
||||
D. `k > 1`
|
||||
|
||||
( ) 38. ⑤处应填
|
||||
A. `k += f[u]`
|
||||
B. `k -= f[u]`
|
||||
C. `--k`
|
||||
D. `++k`
|
||||
|
||||
**(2) (最大值之和)** 给定整数序列 a₀, a₁, ..., aₙ₋₁,求该序列所有非空连续子序列的最大值之和。上述参数满足 1≤n≤10⁵ 和 1≤|aᵢ|≤10⁹。
|
||||
一个序列的非空连续子序列可以用两个下标 l 和 r (其中 0≤l≤r<n)表示,对应的序列为 aₗ, aₗ₊₁, ..., aᵣ。两个非空连续子序列不同,当且仅当下标不同。
|
||||
例如,当原序列为 `[1,2,1,2]`时,要计算子序列 `[1]`, `[2]`, `[1]`, `[2]`, `[1,2]`, `[2,1]`, `[1,2]`, `[1,2,1]`, `[2,1,2]`, `[1,2,1,2]` 的最大值之和,答案为 18。
|
||||
解决该问题有许多算法,以下程序使用分治算法,时间复杂度 O(n log n)。试补全程序。
|
||||
```cpp
|
||||
#include <iostream>
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
|
||||
const int MAXN = 100000;
|
||||
int n;
|
||||
int a[MAXN];
|
||||
long long ans;
|
||||
|
||||
void solve(int l, int r) {
|
||||
if (l + 1 == r) {
|
||||
ans += a[l];
|
||||
return;
|
||||
}
|
||||
int mid = (l + r) >> 1;
|
||||
std::vector<int> pre(a + mid, a + r);
|
||||
for (int i = 1; i < r - mid; ++i) ①;
|
||||
std::vector<long long> sum(r - mid + 1);
|
||||
for (int i = 0; i < r - mid; ++i) sum[i + 1] = sum[i] + pre[i];
|
||||
for (int i = mid - 1, j = mid, max_val = 0; i >= l; --i) { // 译者注:max应为max_val
|
||||
while (j < r && ②) ++j;
|
||||
max_val = std::max(max_val, a[i]);
|
||||
ans += ③;
|
||||
ans += ④;
|
||||
}
|
||||
solve(l, mid);
|
||||
solve(mid, r);
|
||||
}
|
||||
|
||||
int main() {
|
||||
std::cin >> n;
|
||||
for (int i = 0; i < n; ++i) std::cin >> a[i];
|
||||
⑤;
|
||||
std::cout << ans << std::endl;
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
( ) 39. ①处应填
|
||||
A. `pre[i] = std::max(pre[i - 1], a[i - 1])`
|
||||
B. `pre[i + 1] = std::max(pre[i], pre[i + 1])`
|
||||
C. `pre[i] = std::max(pre[i - 1], a[i])`
|
||||
D. `pre[i] = std::max(pre[i], pre[i - 1])`
|
||||
|
||||
( ) 40. ②处应填
|
||||
A. `a[j] < max_val`
|
||||
B. `a[j] < a[i]`
|
||||
C. `pre[j - mid] < max_val`
|
||||
D. `pre[j - mid] > max_val`
|
||||
|
||||
( ) 41. ③处应填
|
||||
A. `(long long)(j - mid) * max_val`
|
||||
B. `(long long)(j - mid) * (l - 1) * max_val`
|
||||
C. `sum[j - mid]`
|
||||
D. `sum[j - mid] * (i - 1)`
|
||||
|
||||
( ) 42. ④处应填
|
||||
A. `(long long)(r - j) * max_val`
|
||||
B. `(long long)(r - j) * (mid - i) * max_val`
|
||||
C. `sum[r - mid] - sum[j - mid]`
|
||||
D. `(sum[r - mid] - sum[j - mid]) * (mid - i)`
|
||||
|
||||
( ) 43. ⑤处应填
|
||||
A. `solve(0, n)`
|
||||
B. `solve(0, n - 1)`
|
||||
C. `solve(1, n)`
|
||||
D. `solve(1, n - 1)`
|
||||
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
+61
@@ -0,0 +1,61 @@
|
||||
### **2024 CCF 非专业级别软件能力认证第一轮 (CSP-J1) 参考答案**
|
||||
|
||||
#### **一、单项选择题**
|
||||
1. **C**
|
||||
2. **A** (原式为 $(12_{10} - 10_{10}) * 13_{10} - 13_{10} = 2 * 13 - 13 = 13$)
|
||||
3. **B** (A选2人,BC各1人: C(4,2)×C(3,1)×C(3,1)=54; B选2人,AC各1人: C(4,1)×C(3,2)×C(3,1)=36; C选2人,AB各1人: C(4,1)×C(3,1)×C(3,2)=36。总计54+36+36=126)
|
||||
4. **D** (格雷码的特性是相邻两个编码只有一位不同)
|
||||
5. **D** (1MB = 1024 * 1024 Bytes = 1024 * 1024 * 8 bits = 8388608 bits)
|
||||
6. **C** (`struct` 是构造数据类型,不是基本数据类型)
|
||||
7. **D** (`repeat-until` 是 Pascal 等语言的语法)
|
||||
8. **B** (字符'a'的ASCII码是97,97 + 13 = 110,110对应的字符是'n')
|
||||
9. **B** (2⁹ = 512, 2¹⁰ = 1024。所以最多比较10次)
|
||||
10. **A** (Notepad是记事本应用软件)
|
||||
11. **B** (图论基本定理:每条边连接两个顶点,为总度数贡献2)
|
||||
12. **A** (通过前序和中序遍历结果可以唯一确定一棵二叉树,从而得到其后序遍历)
|
||||
13. **D** (栈的特性是后进先出,可逐项模拟验证,D项无法实现)
|
||||
14. **A** (捆绑法:将3个女生视为一个整体,与5个男生进行全排列,有 `P(6,6)` 种方法。3个女生内部也有 `P(3,3)` 种排列。总数为 `6! * 3! = 720 * 6 = 4320`)
|
||||
15. **B**
|
||||
|
||||
---
|
||||
#### **二、阅读程序**
|
||||
|
||||
**(1)**
|
||||
16. **√** (10以内的质数是2, 3, 5, 7,共4个,和为17)
|
||||
17. **×** (判断逻辑依然正确,20以内的质数有8个,输出不会变为6)
|
||||
18. **√**
|
||||
19. **B** (1到50的质数之和为328)
|
||||
20. **A** (修改后,任何大于1的数 `p` 在循环到 `i=p` 时都会因 `p % p == 0` 而被误判为非质数,导致结果错误)
|
||||
|
||||
**(2)**
|
||||
21. **√** (模拟DP过程:dp[1]=10, dp[2]=min(10,0)+15=15, dp[3]=min(15,10)+20=30。返回min(dp[3], dp[2])即min(30,15)=15)
|
||||
22. **×** (不会产生编译错误,但可能会因访问数组负数下标而产生运行时错误)
|
||||
23. **×** (程序计算的是到达楼顶的最小花费路径,不一定是单个最小元素)
|
||||
24. **A** (模拟DP过程,最终返回min(dp[10], dp[9]) = min(6, 104) = 6)
|
||||
25. **B** (模拟DP过程,最终返回min(dp[7], dp[6]) = min(45, 30) = 30)
|
||||
26. **A** (修改后模拟计算:dp[1]=5, dp[2]=dp[1]+cost[0]=5+5=10, dp[3]=dp[2]+cost[1]=10+10=20。返回min(20,10)=10)
|
||||
|
||||
**(3)**
|
||||
27. **×** (`customFunction(2, 3)` 返回 8。题目问的是函数的返回值,而不是最终输出。最终输出 `pow(8, 2)` 是64)
|
||||
28. **√** (b为负数,`b-1` 永远不会等于0,导致无限递归)
|
||||
29. **√** (b越大,递归深度越大,运行时间越长)
|
||||
30. **B** (该函数计算 `a * (b + 1)`,即 `5 * (4 + 1) = 25`)
|
||||
31. **C** (`customFunction(3, 3)` 返回 `3 * (3 + 1) = 12`。程序最终输出 `pow(12, 2)` 即 144)
|
||||
32. **D** (修改后递归计算:f(3,3) = 3+f(2,2) = 3+2+f(1,1) = 3+2+1+f(0,0) = 3+2+1+0=6。最终输出`pow(6,2)`即36)
|
||||
|
||||
---
|
||||
#### **三、完善程序**
|
||||
|
||||
**(1) 判断平方数**
|
||||
33. **A** (从1开始检查)
|
||||
34. **B** (循环的上界是原数的平方根,没有必要超过它)
|
||||
35. **C** (判断`i`的平方是否等于`num`)
|
||||
36. **C** (如果找到,说明是平方数,返回`true`)
|
||||
37. **D** (如果循环结束都没找到,说明不是平方数,返回`false`)
|
||||
|
||||
**(2) 汉诺塔问题**
|
||||
38. **B** (递归的边界条件:当只剩一个盘子时,直接移动)
|
||||
39. **B** (对应 `move(src, tgt)`)
|
||||
40. **B** (第一步:将 `i-1` 个盘子从 `src` 经由 `tgt` 移到 `tmp`)
|
||||
41. **B** (第三步的盘子数量为 `i-1`)
|
||||
42. **B** (第三步:将 `i-1` 个盘子从 `tmp` 经由 `src` 移到 `tgt`)
|
||||
+299
@@ -0,0 +1,299 @@
|
||||
<center><font size="6"><b>2024 CCF 非专业级别软件能力认证第一轮</b></font></center>
|
||||
<center><font size="4"><b>(CSP-J1) 入门级 C++语言试题</b></font></center>
|
||||
<center><font size="4"><b>认证时间:2024 年 9 月 16 日 09:30~11:30</b></font></center>
|
||||
|
||||
**考生注意事项:**
|
||||
- 试题纸共有 10 页,答题纸共有 1 页,满分 100 分。请在答题纸上作答,写在试题纸上的一律无效。
|
||||
- 不得使用任何电子设备(如计算器、手机、电子词典等)或查阅任何书籍资料。
|
||||
|
||||
---
|
||||
#### **一、 单项选择题(共 15 题, 每题 2 分, 共计 30 分; 每题有且有一个正确选项)**
|
||||
|
||||
( ) 1. 32位 `int` 类型的存储范围是
|
||||
A. -2147483647 ~ +2147483647
|
||||
B. -2147483647 ~ +2147483648
|
||||
C. -2147483648 ~ +2147483647
|
||||
D. -2147483648 ~ +2147483648
|
||||
|
||||
( ) 2. 计算 $(14_8 - 1010_2) * D_{16} - 1101_2$ 的结果,并选择答案的十进制值
|
||||
A. 13 B. 14 C. 15 D. 16
|
||||
|
||||
( ) 3. 某公司有 10 名员工,分为 3 个部门:A 部门有 4 名员工,B 部门有 3 名员工,C部门有 3 名员工。现需要从这 10 名员工中选出 4 名组成一个工作组,且每个部门至少要有 1 人。问有多少种选择方式?
|
||||
A. 120 B. 126 C. 132 D. 238
|
||||
|
||||
( ) 4. 以下哪个序列对应数组0至8的4位二进制格雷码(Gray code)
|
||||
A. 0000, 0001, 0011, 0010, 0110, 0111, 0101, 1000
|
||||
B. 0000, 0001, 0011, 0010, 0110, 0111, 0100, 0101
|
||||
C. 0000, 0001, 0011, 0010, 0100, 0101, 0111, 0110
|
||||
D. 0000, 0001, 0011, 0010, 0110, 0111, 0101, 0100
|
||||
|
||||
( ) 5. 记 1KB 为 1024 字节(byte),1MB 为 1024KB,那么 1MB 是多少二进制位(bit)?
|
||||
A. 1000000 B. 1048576 C. 8000000 D. 8388608
|
||||
|
||||
( ) 6. 以下哪个不是C++中的基本数据类型?
|
||||
A. int B. float C. struct D. char
|
||||
|
||||
( ) 7. 以下哪个不是C++中的循环语句?
|
||||
A. for B. while C. do-while D. repeat-until
|
||||
|
||||
( ) 8. 在C/C++中,`(char)('a' + 13)` 与下面的哪一个值相等
|
||||
A. 'm' B. 'n' C. 'z' D. '3'
|
||||
|
||||
( ) 9. 假设有序表中有1000个元素,则用二分法查找元素最多需要比较\_\_\_\_次
|
||||
A. 25 B. 10 C. 7 D. 1
|
||||
|
||||
( ) 10. 下面哪一个不是操作系统名字
|
||||
A. Notepad B. Linux C. Windows D. macOS
|
||||
|
||||
( ) 11. 在无向图中,所有顶点的度数之和等于
|
||||
A. 图的边数 B. 图的边数的两倍 C. 图的顶点数 D. 图的顶点数的两倍
|
||||
|
||||
( ) 12. 已知二叉树的前序遍历为 `[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,F,G,A,C]` C. `[D,B,E,F,G,C,A]` D. `[D,E,B,F,G,A,C]`
|
||||
|
||||
( ) 13. 给定一个空栈,支持入栈和出栈操作。若入栈操作的元素依次是1,2,3,4,5,6,其中1最先入栈,6最后入栈,下面哪种出栈顺序是不可能的
|
||||
A. 6 5 4 3 2 1 B. 1 6 5 4 3 2 C. 2 4 6 5 3 1 D. 1 3 5 2 4 6
|
||||
|
||||
( ) 14. 有5个男生和3个女生站成一排,规定3个女生必须相邻,问有多少种不同的排列方式?
|
||||
A. 4320 种 B. 5040 种 C. 3600 种 D. 2880 种
|
||||
|
||||
( ) 15. 编译器的主要作用是什么?
|
||||
A. 直接执行源代码 B. 将源代码转换为机器代码
|
||||
C. 进行代码调试 D. 管理程序运行时的内存
|
||||
|
||||
---
|
||||
#### **二、阅读程序 (程序输入不超过数组或字符串定义的范围,判断题正确填 √,错误填 ×; 除特殊说明外,判断题 1.5 分,选择题 3 分,共计 40 分)**
|
||||
|
||||
**(1)**
|
||||
|
||||
```cpp
|
||||
1 #include <iostream>
|
||||
2 using namespace std;
|
||||
3
|
||||
4 bool isPrime(int n) {
|
||||
5 if (n <= 1) {
|
||||
6 return false;
|
||||
7 }
|
||||
8 for (int i = 2; i * i <= n; i++) {
|
||||
9 if (n % i == 0) {
|
||||
10 return false;
|
||||
11 }
|
||||
12 }
|
||||
13 return true;
|
||||
14 }
|
||||
15
|
||||
16 int countPrimes(int n) {
|
||||
17 int count = 0;
|
||||
18 for (int i = 2; i <= n; i++) {
|
||||
19 if (isPrime(i)) {
|
||||
20 count++;
|
||||
21 }
|
||||
22 }
|
||||
23 return count;
|
||||
24 }
|
||||
25
|
||||
26 int sumPrimes(int n) {
|
||||
27 int sum = 0;
|
||||
28 for (int i = 2; i <= n; i++) {
|
||||
29 if (isPrime(i)) {
|
||||
30 sum += i;
|
||||
31 }
|
||||
32 }
|
||||
33 return sum;
|
||||
34 }
|
||||
35
|
||||
36 int main() {
|
||||
37 int x;
|
||||
38 cin >> x;
|
||||
39 cout << countPrimes(x) << " " << sumPrimes(x) << endl;
|
||||
40 return 0;
|
||||
41 }
|
||||
```
|
||||
|
||||
**判断题**
|
||||
( ) 16. 当输入为“10”时,程序的第一个输出为“4”,第二个输出为“17”。
|
||||
( ) 17. 若将 `isPrime()` 函数中的条件改为 `i <= n/2`,输入“20”时,`countPrimes(20)` 的输出将变为“6”。
|
||||
( ) 18. `sumPrimes` 函数计算的是从2到n之间的所有素数之和。
|
||||
|
||||
**单选题**
|
||||
( ) 19. 当输入为“50”时,`sumPrimes(50)` 的输出为
|
||||
A. 1060 B. 328 C. 381 D. 275
|
||||
|
||||
( ) 20. 如果将 `for(int i = 2; i * i <= n; i++)` 改为 `for(int i = 2; i <= n; i++)`,输入“10”时,程序的输出
|
||||
A. 将不能正确计算10以内素数个数及其和
|
||||
B. 仍然输出“4”和“17”
|
||||
C. 输出“3”和“10”
|
||||
D. 输出结果不变,但运行时间更短
|
||||
|
||||
**(2)**
|
||||
```cpp
|
||||
1 #include <iostream>
|
||||
2 #include <vector>
|
||||
3 using namespace std;
|
||||
4
|
||||
5 int compute(vector<int> &cost) {
|
||||
6 int n = cost.size();
|
||||
7 vector<int> dp(n + 1, 0);
|
||||
8 dp[1] = cost[0];
|
||||
9
|
||||
10 for (int i = 2; i <= n; i++) {
|
||||
11 dp[i] = min(dp[i - 1], dp[i - 2]) + cost[i - 1];
|
||||
12 }
|
||||
13 return min(dp[n], dp[n - 1]);
|
||||
14 }
|
||||
15
|
||||
16 int main() {
|
||||
17 int n;
|
||||
18 cin >> n;
|
||||
19 vector<int> cost(n);
|
||||
20 for (int i = 0; i < n; i++) {
|
||||
21 cin >> cost[i];
|
||||
22 }
|
||||
23 cout << compute(cost) << endl;
|
||||
24 return 0;
|
||||
25 }
|
||||
```
|
||||
|
||||
**判断题**
|
||||
( ) 21. 当输入的 `cost` 数组为 `{10, 15, 20}` 时,程序的输出为15。
|
||||
( ) 22. 如果将 `dp[i-1]` 改为 `dp[i-3]`,程序可能会产生编译错误。
|
||||
( ) 23. (2分) 程序总是输出 `cost` 数组中的最小的元素。
|
||||
|
||||
**单选题**
|
||||
( ) 24. 当输入的 `cost` 数组为 `{1, 100, 1, 1, 1, 100, 1, 1, 100, 1}` 时,程序的输出为
|
||||
A. 6 B. 7 C. 8 D. 9
|
||||
|
||||
( ) 25. (4分) 如果输入的 `cost` 数组为 `{10, 15, 30, 5, 5, 10, 20}`,程序的输出为
|
||||
A. 25 B. 30 C. 35 D. 40
|
||||
|
||||
( ) 26. 若将代码中的 `min(dp[i - 1], dp[i - 2]) + cost[i - 1]` 修改为 `dp[i - 1] + cost[i - 2]`,输入 `cost` 数组为 `{5, 10, 15}` 时,程序的输出为
|
||||
A. 10 B. 15 C. 20 D. 25
|
||||
|
||||
**(3)**
|
||||
```cpp
|
||||
1 #include <iostream>
|
||||
2 #include <cmath>
|
||||
3 using namespace std;
|
||||
4
|
||||
5 int customFunction(int a, int b) {
|
||||
6 if (b == 0) {
|
||||
7 return a;
|
||||
8 }
|
||||
9 return a + customFunction(a, b - 1);
|
||||
10 }
|
||||
11
|
||||
12 int main() {
|
||||
13 int x, y;
|
||||
14 cin >> x >> y;
|
||||
15 int result = customFunction(x, y);
|
||||
16 cout << pow(result, 2) << endl;
|
||||
17 return 0;
|
||||
18 }
|
||||
```
|
||||
|
||||
**判断题**
|
||||
( ) 27. 当输入为“2 3”时,`customFunction(2, 3)` 的返回值为“64”。
|
||||
( ) 28. 当 `b` 为负数时,`customFunction(a, b)` 会陷入无限递归。
|
||||
( ) 29. 当 `b` 的值越大,程序的运行时间越长。
|
||||
|
||||
**单选题**
|
||||
( ) 30. 当输入为“5 4”时,`customFunction(5, 4)` 的返回值为
|
||||
A. 5 B. 25 C. 250 D. 625
|
||||
|
||||
( ) 31. 如果输入 `x=3` 和 `y=3`,则程序的最终输出为
|
||||
A. 27 B. 81 C. 144 D. 256
|
||||
|
||||
( ) 32. (4分) 若将 `customFunction` 函数改为 `return a + customFunction(a - 1, b - 1);` 并输入“3 3”,则程序的最终输出为
|
||||
A. 9 B. 16 C. 25 D. 36
|
||||
|
||||
---
|
||||
#### **三、完善程序 (程序输入不超过数组或字符串定义的范围; 每题 3 分,共计 30 分)**
|
||||
|
||||
**(1) (判断平方数)问题:** 给定一个正整数n,判断这个数是不是完全平方数,即存在一个正整数x,使得x的平方等于n。试补全程序。
|
||||
```cpp
|
||||
#include <iostream>
|
||||
#include <cmath>
|
||||
using namespace std;
|
||||
bool isSquare(int num) {
|
||||
int i = __(1)__;
|
||||
int bound = __(2)__;
|
||||
for (; i <= bound; ++i) {
|
||||
if (__(3)__) {
|
||||
return __(4)__;
|
||||
}
|
||||
}
|
||||
return __(5)__;
|
||||
}
|
||||
|
||||
int main() {
|
||||
int n;
|
||||
cin >> n;
|
||||
if (isSquare(n)) {
|
||||
cout << n << " is a Square number" << endl;
|
||||
} else {
|
||||
cout << n << " is not a Square number" << endl;
|
||||
}
|
||||
}
|
||||
```
|
||||
( ) 33. (1)处应填
|
||||
A. 1 B. 2 C. 3 D. 4
|
||||
|
||||
( ) 34. (2)处应填
|
||||
A. `(int)floor(sqrt(num) - 1)`
|
||||
B. `(int)floor(sqrt(num))`
|
||||
C. `floor(sqrt(num / 2)) - 1`
|
||||
D. `floor(sqrt(num / 2))`
|
||||
|
||||
( ) 35. (3)处应填
|
||||
A. `num == 2 * i` B. `num == 2 + i`
|
||||
C. `num == i * i` D. `num == i`
|
||||
|
||||
( ) 36. (4)处应填
|
||||
A. `num == 2 + i` B. `num == 2 * i` C. `true` D. `false`
|
||||
|
||||
( ) 37. (5)处应填
|
||||
A. `num == i * i` B. `num != 2 * i` C. `true` D. `false`
|
||||
|
||||
**(2) (汉诺塔问题)** 给定三根柱子,分别标记为A、B和C。初始状态下,柱子A上有若干个圆盘,这些圆盘从上到下按从小到大的顺序排列。任务是将这些圆盘全部移到柱子C上,且必须保持原有顺序不变。在移动过程中,需要遵守以下规则:
|
||||
1. 只能从一根柱子的顶部取出圆盘,并将其放入另一根柱子的顶部。
|
||||
2. 每次只能移动一个圆盘。
|
||||
3. 小圆盘必须始终在大圆盘之上。
|
||||
试补全程序。
|
||||
```cpp
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
void move(char src, char tgt) {
|
||||
cout << "从柱子" << src << "挪到柱子" << tgt << endl;
|
||||
}
|
||||
|
||||
void dfs(int i, char src, char tmp, char tgt) {
|
||||
if (i == __(1)__) {
|
||||
move(__(2)__);
|
||||
return;
|
||||
}
|
||||
dfs(i - 1, __(3)__);
|
||||
move(src, tgt);
|
||||
dfs(__(4)__, __(5)__);
|
||||
}
|
||||
|
||||
int main() {
|
||||
int n;
|
||||
cin >> n;
|
||||
dfs(n, 'A', 'B', 'C');
|
||||
}
|
||||
```
|
||||
( ) 38. (1)处应填
|
||||
A. 0 B. 1 C. 2 D. 3
|
||||
|
||||
( ) 39. (2)处应填
|
||||
A. `src, tmp` B. `src, tgt` C. `tmp, tgt` D. `tgt, tmp`
|
||||
|
||||
( ) 40. (3)处应填
|
||||
A. `src, tmp, tgt` B. `src, tgt, tmp` C. `tgt, tmp, src` D. `tgt, src, tmp`
|
||||
|
||||
( ) 41. (4)处应填
|
||||
A. `i` B. `i - 1` C. `tmp` D. `src`
|
||||
|
||||
( ) 42. (5)处应填
|
||||
A. `src, tmp, tgt` B. `tmp, src, tgt` C. `src, tgt, tmp` D. `tgt, src, tmp`
|
||||
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
@@ -0,0 +1,903 @@
|
||||
# CSP-J 2026 第一轮试卷:参考答案与详细解析
|
||||
|
||||
> 根据用户提供的《CSP-J-2026-试卷与答案.pdf》整理,题号及选项对应该文件。本文对全部 43 题逐题推导,所得答案与文件卷末参考答案一致。判断题中 A 表示正确,B 表示错误。本文沿用所提供文件的标题,不另行认定其官方来源。
|
||||
|
||||
## 一、答案速查
|
||||
|
||||
| 题号 | 答案 | 题号 | 答案 | 题号 | 答案 |
|
||||
|---|---|---|---|---|---|
|
||||
| 1 | B | 16 | A(正确) | 31 | B |
|
||||
| 2 | D | 17 | B(错误) | 32 | D |
|
||||
| 3 | C | 18 | A(正确) | 33 | C |
|
||||
| 4 | C | 19 | A | 34 | D |
|
||||
| 5 | B | 20 | C | 35 | B |
|
||||
| 6 | D | 21 | C | 36 | D |
|
||||
| 7 | D | 22 | A(正确) | 37 | B |
|
||||
| 8 | C | 23 | B(错误) | 38 | C |
|
||||
| 9 | B | 24 | B(错误) | 39 | B |
|
||||
| 10 | A | 25 | B | 40 | D |
|
||||
| 11 | A | 26 | A | 41 | C |
|
||||
| 12 | D | 27 | C | 42 | A |
|
||||
| 13 | C | 28 | B(错误) | 43 | D |
|
||||
| 14 | A | 29 | A(正确) | | |
|
||||
| 15 | B | 30 | A(正确) | | |
|
||||
|
||||
分值:第 1~15 题每题 2 分;第 16 题 1 分;第 17、18、22、23、24、28、29、30 题每题 1.5 分;其余每题 3 分,共 100 分。
|
||||
|
||||
## 二、单项选择题(第 1~15 题)
|
||||
|
||||
### 第 1 题:精确存储大整数
|
||||
|
||||
**答案:B,`long long`。**
|
||||
|
||||
需要精确存储的整数是 $10^{18}+1$。
|
||||
|
||||
按竞赛中通常采用的类型规格,32 位有符号 `int` 的最大值为 $2^{31}-1=2147483647$,无法容纳这个数;64 位有符号 `long long` 的最大值为 $2^{63}-1\approx9.22\times10^{18}$,能够精确存储。
|
||||
|
||||
`float` 和 `double` 虽然可以表示数量级很大的数,但有效精度有限。常见的 IEEE 754 `double` 有 53 位二进制有效精度,能够连续精确表示的非负整数范围只到 $2^{53}$。在 $10^{18}$ 附近,相邻可表示数的间距是 128,不能精确表示 $10^{18}+1$;`float` 的精度更低。
|
||||
|
||||
**易错点:表示范围大,不等于能精确存储范围内的每一个整数。**
|
||||
|
||||
### 第 2 题:十六进制转八进制
|
||||
|
||||
**答案:D,1365。**
|
||||
|
||||
先转为十进制:
|
||||
|
||||
$$
|
||||
(2F5)_{16}=2\times16^2+15\times16+5=757。
|
||||
$$
|
||||
|
||||
再检查:
|
||||
|
||||
$$
|
||||
(1365)_8=1\times8^3+3\times8^2+6\times8+5=757。
|
||||
$$
|
||||
|
||||
也可以利用二进制中转:每个十六进制位转成 4 位二进制,再从右向左按 3 位分组。
|
||||
|
||||
```text
|
||||
2F5₁₆ = 0010 1111 0101₂
|
||||
= 001 011 110 101₂
|
||||
= 1 3 6 5₈
|
||||
```
|
||||
|
||||
### 第 3 题:整数除法与取余
|
||||
|
||||
**答案:C,7。**
|
||||
|
||||
`a=7`、`b=3`,整数除法 `7/3=2`,取余 `7%3=1`。
|
||||
|
||||
```cpp
|
||||
a / b * b + a % b
|
||||
= 2 * 3 + 1
|
||||
= 7
|
||||
```
|
||||
|
||||
正整数除法满足:被除数 = 商 × 除数 + 余数。
|
||||
|
||||
### 第 4 题:判断合法出栈序列
|
||||
|
||||
**答案:C,3、1、2、4。**
|
||||
|
||||
栈遵循“后进先出”。要先弹出 3,必须先依次压入 1、2、3。弹出 3 后,栈中从底到顶是 1、2,此时必须先弹出 2,才能弹出 1,因此不可能紧接着输出 1。
|
||||
|
||||
其他选项均可实现:
|
||||
|
||||
- A:压入 1、2,弹出 2;压入 3、4,依次弹出 4、3、1。
|
||||
- B:每压入一个数就立即弹出。
|
||||
- D:压入并弹出 1;压入 2、3、4,再依次弹出 4、3、2。
|
||||
|
||||
### 第 5 题:完全二叉树的叶子数
|
||||
|
||||
**答案:B,50。**
|
||||
|
||||
将完全二叉树的结点按层序编号为 1~100。编号为 $i$ 的结点,其左孩子编号为 $2i$。
|
||||
|
||||
当 $2i\le100$ 时有孩子,即编号 1~50 的结点不是叶子;编号 51~100 的结点都是叶子,共 50 个。
|
||||
|
||||
一般地,含 $N$ 个结点的完全二叉树叶子数为:
|
||||
|
||||
$$
|
||||
N-\left\lfloor\frac N2\right\rfloor=\left\lceil\frac N2\right\rceil。
|
||||
$$
|
||||
|
||||
### 第 6 题:3 或 5 的倍数之和
|
||||
|
||||
**答案:D,2418。**
|
||||
|
||||
条件中的 `||` 表示满足任意一个条件即可,因此应求 1~100 中所有 3 或 5 的倍数之和。
|
||||
|
||||
3 的倍数之和:
|
||||
|
||||
$$
|
||||
3(1+2+\cdots+33)=3\times\frac{33\times34}{2}=1683。
|
||||
$$
|
||||
|
||||
5 的倍数之和:
|
||||
|
||||
$$
|
||||
5(1+2+\cdots+20)=1050。
|
||||
$$
|
||||
|
||||
15 的倍数被重复计算,需要减去:
|
||||
|
||||
$$
|
||||
15(1+2+\cdots+6)=315。
|
||||
$$
|
||||
|
||||
最终结果为 $1683+1050-315=2418$。这就是容斥原理。
|
||||
|
||||
### 第 7 题:每次上 1、2、3 级台阶
|
||||
|
||||
**答案:D,81。**
|
||||
|
||||
设 $f(i)$ 为到达第 $i$ 级台阶的方法数。按照最后一步走了几级分类:
|
||||
|
||||
$$
|
||||
f(i)=f(i-1)+f(i-2)+f(i-3)。
|
||||
$$
|
||||
|
||||
边界为 $f(0)=1$,表示不走也是到达地面的一种方式;也可以直接从 $f(1)=1,f(2)=2,f(3)=4$ 开始推。
|
||||
|
||||
| 台阶数 $i$ | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
|
||||
|---|---|---|---|---|---|---|---|---|---|
|
||||
| 方法数 $f(i)$ | 1 | 1 | 2 | 4 | 7 | 13 | 24 | 44 | 81 |
|
||||
|
||||
### 第 8 题:BFS 的入队次序
|
||||
|
||||
**答案:C,14 个。**
|
||||
|
||||
坐标按 `(行,列)` 表示,起点为 `(0,0)`,终点为 `(3,4)`。必须同时遵守“队首先出”和邻居按“上、下、左、右”检查。
|
||||
|
||||
首次入队的完整顺序,直到 E 入队为止:
|
||||
|
||||
| 入队编号 | 格子坐标 | 由哪个格子发现 |
|
||||
|---|---|---|
|
||||
| 1 | (0,0),S | 初始入队 |
|
||||
| 2 | (1,0) | (0,0) |
|
||||
| 3 | (0,1) | (0,0) |
|
||||
| 4 | (2,0) | (1,0) |
|
||||
| 5 | (1,1) | (1,0) |
|
||||
| 6 | (0,2) | (0,1) |
|
||||
| 7 | (2,1) | (2,0) |
|
||||
| 8 | (1,2) | (1,1) |
|
||||
| 9 | (2,2) | (2,1) |
|
||||
| 10 | (3,2) | (2,2) |
|
||||
| 11 | (4,2) | (3,2) |
|
||||
| 12 | (3,3) | (3,2) |
|
||||
| 13 | (4,1) | (4,2) |
|
||||
| 14 | (3,4),E | (3,3) |
|
||||
|
||||
关键细节:处理 `(3,2)` 时,先发现下面的 `(4,2)`,再发现右边的 `(3,3)`。所以在 `(3,3)` 发现 E 之前,`(4,2)` 已经出队,并使 `(4,1)` 入队。
|
||||
|
||||
**易错点:题目统计累计入队过多少格,不是当前队列长度,也不是最短路径上的格子数。**
|
||||
|
||||
### 第 9 题:最大公约数条件
|
||||
|
||||
**答案:B,6 个。**
|
||||
|
||||
因为 $\gcd(n,60)=6$,所以令 $n=6t$,则:
|
||||
|
||||
$$
|
||||
\gcd(6t,60)=6\gcd(t,10)=6,
|
||||
$$
|
||||
|
||||
即 $\gcd(t,10)=1$。由 $1\le n\le100$,可得 $1\le t\le16$。
|
||||
|
||||
在 1~16 中排除 2 或 5 的倍数,剩下:
|
||||
|
||||
$$
|
||||
t=1,3,7,9,11,13。
|
||||
$$
|
||||
|
||||
对应 $n=6,18,42,54,66,78$,共 6 个。
|
||||
|
||||
### 第 10 题:最少硬币数
|
||||
|
||||
**答案:A,3 枚。**
|
||||
|
||||
可以用 $4+4+1=9$,因此最多需要 3 枚。
|
||||
|
||||
1 枚显然不行;2 枚可能组成的金额为 $2,5,7,8,10,12$,没有 9,因此最少为 3 枚。
|
||||
|
||||
**易错点:每次选最大面值的贪心策略在这里不成立。**按该策略会选 $6+1+1+1$,需要 4 枚。
|
||||
|
||||
### 第 11 题:指针与数组下标
|
||||
|
||||
**答案:A,`14,13`。**
|
||||
|
||||
初始数组为 `[1,3,5,7,9]`,`p=a+2`,即 `p` 指向 `a[2]`。
|
||||
|
||||
第一条赋值:
|
||||
|
||||
```cpp
|
||||
*(p - 1) = p[0] + p[2];
|
||||
```
|
||||
|
||||
等价于 `a[1]=a[2]+a[4]=5+9=14`。
|
||||
|
||||
第二条赋值:
|
||||
|
||||
```cpp
|
||||
p[1] = *(a + 1) - a[0];
|
||||
```
|
||||
|
||||
等价于 `a[3]=a[1]-a[0]=14-1=13`。注意这里的 `a[1]` 已被上一条语句修改。
|
||||
|
||||
所以输出 `14,13`。
|
||||
|
||||
### 第 12 题:二分查找的最坏比较次数
|
||||
|
||||
**答案:D,10 次。**
|
||||
|
||||
每比较一个中间元素,就将候选区间缩小到大约原来的一半。按照题目通常的计数方式,一次与中间元素的比较算一次:
|
||||
|
||||
$$
|
||||
\lfloor\log_2 1000\rfloor+1=10。
|
||||
$$
|
||||
|
||||
也可以观察最坏情况下的非空候选区间长度:
|
||||
|
||||
```text
|
||||
1000 → 500 → 250 → 125 → 62 → 31 → 15 → 7 → 3 → 1
|
||||
```
|
||||
|
||||
共需要检查 10 个中间元素。注意题目不是统计具体代码里 `==`、`<` 等运算符的执行总次数。
|
||||
|
||||
### 第 13 题:由前缀和求原数组
|
||||
|
||||
**答案:C,58。**
|
||||
|
||||
已知 $S[i]=3i^2+i$,利用:
|
||||
|
||||
$$
|
||||
a[i]=S[i]-S[i-1]。
|
||||
$$
|
||||
|
||||
因此:
|
||||
|
||||
$$
|
||||
a[10]=(3\times10^2+10)-(3\times9^2+9)=310-252=58。
|
||||
$$
|
||||
|
||||
不要把 `S[10]` 直接当成 `a[10]`:前者是前十项之和。
|
||||
|
||||
### 第 14 题:到所有点的距离和最小
|
||||
|
||||
**答案:A,37。**
|
||||
|
||||
数轴上到各点距离之和,在中位数处取得最小值。七个点已经按从小到大排序,其中位数为第 4 个数 7。
|
||||
|
||||
取 $P=7$:
|
||||
|
||||
$$
|
||||
6+4+3+0+3+8+13=37。
|
||||
$$
|
||||
|
||||
也可以配对证明:对 `(1,20)`、`(3,15)`、`(4,10)`,距离和分别至少为 19、12、6;`P=7` 同时达到这三个下界,且到中间点 7 的距离为 0,所以最小值为 $19+12+6=37$。
|
||||
|
||||
### 第 15 题:度数和与边数
|
||||
|
||||
**答案:B,18。**
|
||||
|
||||
无向图中每条边给两个端点各贡献 1 的度数,因此度数总和等于边数的 2 倍。
|
||||
|
||||
$$
|
||||
2|E|=4\times3+(10-4)\times4=36,\qquad |E|=18。
|
||||
$$
|
||||
|
||||
## 三、阅读程序(第 16~33 题)
|
||||
|
||||
### 第一组:除以 2 与二进制数位(第 16~21 题)
|
||||
|
||||
#### 程序整体含义
|
||||
|
||||
初始 `x=1,y=1`。每轮循环无论奇偶,`x` 都增加 1;只有当前 `n` 为奇数时,`y` 才增加 1。随后执行 `n/=2`。
|
||||
|
||||
对非负整数而言,反复执行 `n%2`、`n/=2`,相当于从低位到高位依次读取二进制数位。
|
||||
|
||||
- `x` = 1 + 循环次数。对正数,这就是 1 + 二进制位数。
|
||||
- `y` = 1 + 原数二进制中 1 的个数。
|
||||
- 输入 0 时不进入循环,输出 `1 1`。
|
||||
|
||||
#### 第 16 题
|
||||
|
||||
**答案:A,正确。**
|
||||
|
||||
输入 3,二进制为 `11`。
|
||||
|
||||
| 时刻 | 本轮开始的 n | 操作后的 x | 操作后的 y | n/=2 后 |
|
||||
|---|---|---|---|---|
|
||||
| 初始 | 3 | 1 | 1 | — |
|
||||
| 第 1 轮 | 3,奇数 | 2 | 2 | 1 |
|
||||
| 第 2 轮 | 1,奇数 | 3 | 3 | 0 |
|
||||
|
||||
最终输出 `3 3`。
|
||||
|
||||
#### 第 17 题
|
||||
|
||||
**答案:B,错误。**
|
||||
|
||||
删除奇数分支中的 `++x` 后,`x` 只在处理二进制位 0 时增加,`y` 只在处理二进制位 1 时增加。0 的数量与 1 的数量不一定相等。
|
||||
|
||||
例如输入 `1`,唯一一轮是奇数分支,只增加 `y`,输出为 `1 2`,两个数不相等。
|
||||
|
||||
#### 第 18 题
|
||||
|
||||
**答案:A,正确。**
|
||||
|
||||
原程序每轮一定增加 `x`,增加 `y` 时也一定增加 `x`,而二者初始相等,所以始终有 `x>=y`。
|
||||
|
||||
从二进制角度看,1 的数量不可能超过总位数。输入 0 时二者均为 1,结论也成立。
|
||||
|
||||
#### 第 19 题
|
||||
|
||||
**答案:A,陷入死循环。**
|
||||
|
||||
当条件改为 `while(n>=0)`,`n` 变成 0 后仍满足循环条件,而 `0/2` 永远是 0,无法退出。
|
||||
|
||||
按题目算法层面的讨论,应选死循环。严格按 C++ 语言语义,若无限运行使有符号变量 `x` 溢出,还会涉及未定义行为,但这不改变本题要求识别的循环条件错误。
|
||||
|
||||
#### 第 20 题
|
||||
|
||||
**答案:C,`4 3`。**
|
||||
|
||||
输入 6,二进制为 `110`,共有 3 位,其中有两个 1。所以 `x=1+3=4`,`y=1+2=3`。
|
||||
|
||||
逐轮也可得到:
|
||||
|
||||
```text
|
||||
初始:n=6,x=1,y=1
|
||||
第1轮:6为偶数,x=2,y=1,n=3
|
||||
第2轮:3为奇数,x=3,y=2,n=1
|
||||
第3轮:1为奇数,x=4,y=3,n=0
|
||||
```
|
||||
|
||||
#### 第 21 题
|
||||
|
||||
**答案:C,31 次。**
|
||||
|
||||
第二个数恰好为 2,要求原数二进制中恰好有一个 1,即原数为 2 的非负整数次幂。
|
||||
|
||||
在 $0\le n\le2^{31}-1$ 范围内,这些数是:
|
||||
|
||||
$$
|
||||
2^0,2^1,\ldots,2^{30},
|
||||
$$
|
||||
|
||||
共 31 个。0 的输出第二个数为 1,不符合条件;$2^{31}$ 超出范围。
|
||||
|
||||
### 第二组:高精度加法及输出细节(第 22~27 题)
|
||||
|
||||
#### 程序整体含义
|
||||
|
||||
输入字符串逆序保存到数组中:`a[0]`、`b[0]` 是个位,`a[1]`、`b[1]` 是十位,以此类推。数组为全局变量,未赋值的位置初始为 0。
|
||||
|
||||
令 `L=max(a_len,b_len)`。程序从 `i=0` 算到 `i=L`,多计算一位以容纳最高位进位,然后固定输出 `c[L]` 到 `c[0]`。
|
||||
|
||||
**原程序总是输出 L+1 个字符,不会主动去除前导零。**正常加法中每个 `c[i]` 都在 0~9 之间。
|
||||
|
||||
#### 第 22 题
|
||||
|
||||
**答案:A,正确。**
|
||||
|
||||
`123+456=579`,但 `L=3`,程序输出 `c[3],c[2],c[1],c[0]`。最高位 `c[3]=0`,所以输出 `0579`。
|
||||
|
||||
#### 第 23 题
|
||||
|
||||
**答案:B,错误。**
|
||||
|
||||
即使输入没有前导零,只要最高位没有产生进位,多输出的那一位仍然是 0。例如 `123 456` 的输出就是 `0579`,足以否定“一定不会含有前导零”。
|
||||
|
||||
#### 第 24 题
|
||||
|
||||
**答案:B,错误。**
|
||||
|
||||
删除 `+carry[i]` 会使进位无法参与下一位的计算,但结果不一定严格变小。
|
||||
|
||||
例如输入 `1 2`,本来就没有进位,修改前后都输出 `03`,结果相同。因此“一定比原来的结果小”不成立。
|
||||
|
||||
#### 第 25 题
|
||||
|
||||
**答案:B,`013023`。**
|
||||
|
||||
计算 $12345+678=13023$,原输入最大长度为 5,所以输出 6 位,最前面补出一个 0。
|
||||
|
||||
| 数位 | 两个数的本位及进位 | 本位结果 | 向高位进位 |
|
||||
|---|---|---|---|
|
||||
| 个位 | 5+8+0=13 | 3 | 1 |
|
||||
| 十位 | 4+7+1=12 | 2 | 1 |
|
||||
| 百位 | 3+6+1=10 | 0 | 1 |
|
||||
| 千位 | 2+0+1=3 | 3 | 0 |
|
||||
| 万位 | 1+0+0=1 | 1 | 0 |
|
||||
| 额外最高位 | 0+0+0=0 | 0 | 0 |
|
||||
|
||||
从高位到低位输出为 `013023`。
|
||||
|
||||
#### 第 26 题
|
||||
|
||||
**答案:A,`01010`。**
|
||||
|
||||
将进位条件改为 `c[i]>10` 后,恰好等于 10 时不会进位,也不会减去 10。
|
||||
|
||||
对输入 `95 15`:
|
||||
|
||||
| i | 计算结果 | 是否大于 10 | 最终 c[i] | 下一位收到的进位 |
|
||||
|---|---|---|---|---|
|
||||
| 0 | 5+5+0=10 | 否 | 10 | 0 |
|
||||
| 1 | 9+1+0=10 | 否 | 10 | 0 |
|
||||
| 2 | 0+0+0=0 | 否 | 0 | 0 |
|
||||
|
||||
输出顺序是 `0`、`10`、`10`,直接连接后为 `01010`。
|
||||
|
||||
**易错点:数组元素是整数,不保证始终只有一位。`cout << 10` 会输出两个字符。**
|
||||
|
||||
#### 第 27 题
|
||||
|
||||
**答案:C,长度一定为 n+1,且第一个字符为 `'0'`。**
|
||||
|
||||
两个输入均为 n 位数,所以 `L=n`,原程序固定输出 n+1 位。由于和小于 $10^n$,不存在进入第 n 位的进位,因此 `c[n]=0`,输出的第一个字符一定为 `'0'`。
|
||||
|
||||
### 第三组:质数判断与深度优先搜索(第 28~33 题)
|
||||
|
||||
#### 程序整体含义
|
||||
|
||||
`check_prime(x)` 判断 x 是否为质数。若 x 是合数,则一定有一个不超过 $\sqrt{x}$ 的因子,因此试除到 `i*i<=x` 即可。
|
||||
|
||||
`search_result(x)` 的逻辑为:
|
||||
|
||||
1. 如果 x 不是质数,立即停止这条搜索分支。
|
||||
2. 如果 x 是质数且 `x>=n`,输出 x,并停止向后添加数字。
|
||||
3. 如果 x 是质数且 `x<n`,依次尝试在其末尾添加 0~9。
|
||||
|
||||
所以只有每个非空十进制前缀都是质数的数,才能到达输出位置。遍历方式是深度优先搜索,并不按数值大小排序。
|
||||
|
||||
#### 第 28 题
|
||||
|
||||
**答案:B,错误。**
|
||||
|
||||
输入 10 时,只有起始数字 2、3、5、7 可以继续扩展。一旦得到两位质数,就达到阈值并输出。
|
||||
|
||||
全部输出为:
|
||||
|
||||
```text
|
||||
23
|
||||
29
|
||||
31
|
||||
37
|
||||
53
|
||||
59
|
||||
71
|
||||
73
|
||||
79
|
||||
```
|
||||
|
||||
共 9 行,不是 10 行。比如 11 虽然是质数,但首位 1 不是质数,对应分支早已被剪去。
|
||||
|
||||
#### 第 29 题
|
||||
|
||||
**答案:A,正确。**
|
||||
|
||||
主函数一定调用 `search_result(5)`。5 是质数,且当 `n<=5` 时满足 `5>=n`,所以该调用会直接输出 5。
|
||||
|
||||
#### 第 30 题
|
||||
|
||||
**答案:A,正确。**
|
||||
|
||||
把添加数字范围改为 `1,3,5,7,9`,只是跳过了末位为偶数的扩展。
|
||||
|
||||
扩展得到的数至少有两位,如果末位是 0、2、4、6、8,则它是大于 2 的偶数,必定不是质数。在原程序中,这些分支也会立即返回,既不会输出,也不会继续扩展。
|
||||
|
||||
因此删除这些无效分支后,输出内容和顺序都不变。
|
||||
|
||||
#### 第 31 题
|
||||
|
||||
**答案:B,29。**
|
||||
|
||||
输入 24 时,先从首位 2 开始搜索:
|
||||
|
||||
- 20、21、22 不是质数,返回。
|
||||
- 23 是质数,但小于 24,所以继续扩展。
|
||||
- 230~239 中只有 233、239 是质数,依次输出这两个数。
|
||||
- 返回两位数这一层,24~28 均非质数,随后访问 29。
|
||||
- 29 是质数且不小于 24,因此第 3 行输出 29。
|
||||
|
||||
前几行是:
|
||||
|
||||
```text
|
||||
233
|
||||
239
|
||||
29
|
||||
31
|
||||
37
|
||||
...
|
||||
```
|
||||
|
||||
**易错点:深度优先会先完成 23 的整条分支,再访问 29。**
|
||||
|
||||
#### 第 32 题
|
||||
|
||||
**答案:D。**
|
||||
|
||||
对于输出的任意一个至少两位的数 x,它必然由上一层 `search_result(x/10)` 添加末位得到。上一层只有通过质数检查,才能继续递归。因此删去 x 的末位后得到的数必定是质数。
|
||||
|
||||
其余选项:
|
||||
|
||||
- A 错:输入 24 时,233、239 出现在 29 前面,并非从小到大。
|
||||
- B 错:输入 23 时输出 9 行,输入 24 时输出 10 行;原来输出的 23 被两个后代 233、239 替代,行数增加。
|
||||
- C 错:例如输入 10 时会输出 29、31、59、71、79,个位并不只可能是 3 或 7。
|
||||
|
||||
#### 第 33 题
|
||||
|
||||
**答案:C,14 行。**
|
||||
|
||||
输入 200 时,一位和两位的质数前缀都小于阈值。可继续扩展的两位前缀就是第 28 题列出的 9 个数。
|
||||
|
||||
| 两位质数前缀 | 添加一位后仍为质数的数 | 数量 |
|
||||
|---|---|---|
|
||||
| 23 | 233、239 | 2 |
|
||||
| 29 | 293 | 1 |
|
||||
| 31 | 311、313、317 | 3 |
|
||||
| 37 | 373、379 | 2 |
|
||||
| 53 | 无 | 0 |
|
||||
| 59 | 593、599 | 2 |
|
||||
| 71 | 719 | 1 |
|
||||
| 73 | 733、739 | 2 |
|
||||
| 79 | 797 | 1 |
|
||||
|
||||
这些三位数均不小于 200,所以输出后停止扩展。总行数为 $2+1+3+2+0+2+1+2+1=14$。
|
||||
|
||||
## 四、完善程序(第 34~43 题)
|
||||
|
||||
### 第一组:将 mn 进制转换成 n 进制(第 34~38 题)
|
||||
|
||||
#### 1. 数组究竟表示什么
|
||||
|
||||
这里 $mn$ 表示 $m\times n$。数组 b 以低位在前的顺序,保存已读入部分所代表数值的 n 进制表示:
|
||||
|
||||
$$
|
||||
V=b[0]+b[1]n+b[2]n^2+\cdots+b[len-1]n^{len-1}。
|
||||
$$
|
||||
|
||||
`b[0]` 是个位,`b[len-1]` 是最高位。每轮进位结束后,各位都在 0~n-1 之间;进位前可以暂时超出这个范围。
|
||||
|
||||
#### 2. 每读入一位,要执行哪种运算
|
||||
|
||||
从高到低读入原数的新数位 x,相当于:
|
||||
|
||||
$$
|
||||
V_{新}=V_{旧}\times(mn)+x。
|
||||
$$
|
||||
|
||||
这与读十进制数时“旧数乘 10 再加新数字”是同一个道理。**当前用 n 进制保存数值,不会改变原输入的进制是 mn 这一事实。**
|
||||
|
||||
#### 第 34 题:①
|
||||
|
||||
**答案:D,`b[j - 1] * m`。**
|
||||
|
||||
```cpp
|
||||
for (int j = len; j >= 1; j--)
|
||||
b[j] = b[j - 1] * m;
|
||||
```
|
||||
|
||||
这行同时做了两件事:将数字从第 j-1 位放到第 j 位,并将数字本身乘以 m。
|
||||
|
||||
假设旧数位是 c,它原来代表 $c n^{j-1}$,现在代表:
|
||||
|
||||
$$
|
||||
(cm)n^j=(c n^{j-1})\times mn。
|
||||
$$
|
||||
|
||||
**为什么不能再写 `* n`?**因为位置从 j-1 变成 j,位权已经从 $n^{j-1}$ 变成 $n^j$,相当于自动乘了一次 n。就像十进制的 3 从个位移到十位,数字仍为 3,但代表的数值已经是 30。
|
||||
|
||||
若写成 `b[j]=b[j-1]*m*n`,结合位置变化,实际乘的是 $mn^2$,多乘了一次 n。
|
||||
|
||||
**为什么倒序移动?**从高位向低位赋值,能够保留还没被读取的旧数位;若从低位往高位操作,会提前覆盖后面需要使用的数据。
|
||||
|
||||
#### 第 35 题:②
|
||||
|
||||
**答案:B,`x`。**
|
||||
|
||||
整体高移一位后,最低位空出,相当于为 0。将新读入的 x 加到最低位,直接写:
|
||||
|
||||
```cpp
|
||||
b[0] = x;
|
||||
```
|
||||
|
||||
x 可能大于等于 n,但后面的循环会统一处理进位。
|
||||
|
||||
#### 第 36 题:③
|
||||
|
||||
**答案:D,`b[j] / n`。**
|
||||
|
||||
n 进制中,每满 n 就向高一位进 1,所以需要向高一位增加 `b[j]/n`:
|
||||
|
||||
```cpp
|
||||
b[j + 1] += b[j] / n;
|
||||
```
|
||||
|
||||
必须使用 `+=`,因为高一位可能已有数值,进位应该在原有值上累加。
|
||||
|
||||
#### 第 37 题:④
|
||||
|
||||
**答案:B,`b[j] % n`。**
|
||||
|
||||
进位后,本位留下除以 n 的余数:
|
||||
|
||||
```cpp
|
||||
b[j] = b[j] % n;
|
||||
```
|
||||
|
||||
商送到高位,余数留在本位。进位循环由低位向高位进行,能继续处理进位引起的连锁变化。
|
||||
|
||||
如果向当前最高位之外又进了一位,`len++` 会让循环继续处理这个新数位。
|
||||
|
||||
#### 第 38 题:⑤
|
||||
|
||||
**答案:C,`len > 1 && b[len - 1] == 0`。**
|
||||
|
||||
```cpp
|
||||
while (len > 1 && b[len - 1] == 0)
|
||||
len--;
|
||||
```
|
||||
|
||||
每次读入都先增加 len,但实际数值未必需要这么多位,因此最后需要删除最高位多余的零。
|
||||
|
||||
- 应检查 `b[len-1]`,因为它是最高位;`b[0]` 是最低位,末尾的零不能随意删除。
|
||||
- 必须限制 `len>1`,保证 A=0 时仍保留一位 0。如果使用 `len>0`,可能把唯一的一位零也删掉,导致没有输出。
|
||||
|
||||
#### 3. 完整示例
|
||||
|
||||
取 n=2、m=3,输入的原数是六进制 `1 4`:
|
||||
|
||||
$$
|
||||
(14)_6=1\times6+4=10=(1010)_2。
|
||||
$$
|
||||
|
||||
读完首位 1 后,有效数位是 `[1]`。实际数组可能还带有最高位的零,这些零不影响数值,最后会统一去除。
|
||||
|
||||
读入下一位 4,移动并乘以 m,再写入最低位,得到尚未进位的有效部分 `[4,3]`,表示 $4+3\times2=10$。
|
||||
|
||||
```text
|
||||
[4,3] 第0位为4,向高位进2,本位留0
|
||||
[0,5] 第1位为5,向高位进2,本位留1
|
||||
[0,1,2] 第2位为2,向高位进1,本位留0
|
||||
[0,1,0,1] 所有数位均合法
|
||||
```
|
||||
|
||||
数组低位在前,倒序输出就是 `1 0 1 0`。
|
||||
|
||||
#### 4. 补全后的完整程序
|
||||
|
||||
```cpp
|
||||
#include <iostream>
|
||||
|
||||
constexpr int N = 100005;
|
||||
long long b[N];
|
||||
|
||||
int main() {
|
||||
long long n, m, d;
|
||||
std::cin >> n >> m >> d;
|
||||
int len = 1;
|
||||
|
||||
for (int i = 0; i < d; i++) {
|
||||
long long x;
|
||||
std::cin >> x;
|
||||
|
||||
for (int j = len; j >= 1; j--)
|
||||
b[j] = b[j - 1] * m;
|
||||
b[0] = x;
|
||||
len++;
|
||||
|
||||
for (int j = 0; j < len; j++) {
|
||||
if (b[j] >= n) {
|
||||
b[j + 1] += b[j] / n;
|
||||
b[j] %= n;
|
||||
if (j + 1 == len) len++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
while (len > 1 && b[len - 1] == 0) len--;
|
||||
for (int i = len - 1; i >= 0; i--)
|
||||
std::cout << b[i] << ' ';
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
理解程序时,抓住“读入一位 → 旧数乘 mn 并加 x → 按 n 进制整理进位”。题干虽然称为“逐位除以 n”,但整个读入过程用上述递推式来解释更清楚。
|
||||
|
||||
### 第二组:枚举连续分段,使平均值极差最小(第 39~43 题)
|
||||
|
||||
#### 1. 题意与递归状态
|
||||
|
||||
字符串中的每个十六进制字符分别代表一个整数。例如 `016A` 对应 `[0,1,6,10]`,不是把整串当成一个十六进制整数参与运算。
|
||||
|
||||
在 n-1 个内部间隙中选择至少一个切分位置,将序列分成至少两段。对每段求平均值,目标是让“最大段平均值 - 最小段平均值”尽可能小。
|
||||
|
||||
函数:
|
||||
|
||||
```cpp
|
||||
split(int l, int cnt, double mnb, double mxb)
|
||||
```
|
||||
|
||||
各参数含义如下:
|
||||
|
||||
| 参数 | 含义 |
|
||||
|---|---|
|
||||
| l | 下一段从第 l 个数开始 |
|
||||
| cnt | 已选的内部切分位置数量,即切了几刀 |
|
||||
| mnb | 已确定各段平均值的最小值 |
|
||||
| mxb | 已确定各段平均值的最大值 |
|
||||
|
||||
每次枚举当前段的右端点 r,当前段为 `[l,r]`,然后递归处理从 r+1 开始的剩余部分。
|
||||
|
||||
当 `l>n` 时,所有数已经分完。只有 `cnt>0` 才满足至少切一刀的要求;此时用 `mxb-mnb` 更新最优答案。
|
||||
|
||||
#### 第 39 题:①,十六进制字符转数值
|
||||
|
||||
**答案:B,`c - (c < 'A' ? '0' : 'A' - 10)`。**
|
||||
|
||||
在题设 ASCII 编码和字符范围下:
|
||||
|
||||
- `'0'`~`'9'` 均小于 `'A'`,用 `c-'0'` 得到 0~9。
|
||||
- `'A'`~`'F'` 用 `c-'A'+10` 得到 10~15。
|
||||
|
||||
选项 B 中,字母分支是:
|
||||
|
||||
```cpp
|
||||
c - ('A' - 10) // 等价于 c - 'A' + 10
|
||||
```
|
||||
|
||||
例如 `'A'` 得到 10,`'F'` 得到 15。
|
||||
|
||||
其他选项:A 使用 `c<'9'`,会把字符 `'9'` 错分到字母分支;C 把两个分支颠倒;D 将字母分支中的加 10 错写成减 10。
|
||||
|
||||
#### 第 40 题:②,枚举当前段的右端点
|
||||
|
||||
**答案:D,`int r = l; r <= n; ++r`。**
|
||||
|
||||
段 `[l,r]` 至少包含一个元素,因此最小右端点为 l;最后一段必须能包含第 n 个元素,所以最大右端点为 n。每个位置都可能是右端点,必须逐个枚举。
|
||||
|
||||
- A 从 l+1 开始,会漏掉长度为 1 的段。
|
||||
- B 限制 r<n,无法正常选出结束于 n 的最后一段。
|
||||
- C 每次增加 2,会遗漏部分段长。
|
||||
|
||||
循环中的 `sum+=a[r]` 不断扩展当前段,使 sum 始终等于 `a[l]+...+a[r]`。
|
||||
|
||||
#### 第 41 题:③,正确计算平均值
|
||||
|
||||
**答案:C,`sum * 1.0 / (r - l + 1)`。**
|
||||
|
||||
区间 `[l,r]` 共包含 `r-l+1` 个元素,平均值应为总和除以元素个数。
|
||||
|
||||
`sum*1.0` 先将运算转换为浮点运算,避免整数除法丢失小数部分。
|
||||
|
||||
例如总和为 3、长度为 2:
|
||||
|
||||
```cpp
|
||||
3 / 2 * 1.0 // 先进行整数除法,结果为 1.0
|
||||
3 * 1.0 / 2 // 进行浮点除法,结果为 1.5
|
||||
```
|
||||
|
||||
因此 A 错。B 的分母和运算位置错误,且 r=l 时分母为 0;D 少算了当前段最后一个元素。
|
||||
|
||||
#### 第 42 题:④,递归参数更新
|
||||
|
||||
**答案:A。**
|
||||
|
||||
```cpp
|
||||
r + 1, cnt + (r < n), min(mnb, nwb), max(mxb, nwb)
|
||||
```
|
||||
|
||||
四个参数分别解释如下:
|
||||
|
||||
1. 下一段从 r+1 开始,保证不重叠、不遗漏。
|
||||
2. 只有 r<n 时,r 后面才是一个内部切分位置,才应增加 cnt。
|
||||
3. 新的最小平均值是 `min(mnb,nwb)`。
|
||||
4. 新的最大平均值是 `max(mxb,nwb)`。
|
||||
|
||||
**为什么不能用 `cnt+(r<=n)`?**循环内总有 r<=n,这会连整个序列末尾也算作一次切分。这样不切分的整段 `[1,n]` 也能通过 `cnt>0` 的检查,而唯一一段的最大和最小平均值相等,极差为 0,会让程序错误地对所有输入都得到 0。
|
||||
|
||||
例如输入 `2 09`,唯一合法方案是 `[0] | [9]`,正确极差为 9;不切分时极差为 0,但这不符合题意。
|
||||
|
||||
#### 第 43 题:⑤,递归初始状态
|
||||
|
||||
**答案:D,`1, 0, 1e100, -1e100`。**
|
||||
|
||||
```cpp
|
||||
split(1, 0, 1e100, -1e100);
|
||||
```
|
||||
|
||||
- 数组从下标 1 开始保存数据,所以 l=1。
|
||||
- 尚未选择内部切分位置,所以 cnt=0。
|
||||
- 最小值初始设为很大的数,这样遇到第一个平均值时,`min` 会选中它。
|
||||
- 最大值初始设为很小的数,这样第一次 `max` 也会选中真实平均值。
|
||||
|
||||
实际平均值在 0~15 之间,所以这两个初值足以充当正、负无穷的替代值。
|
||||
|
||||
#### 2. 手算示例:016A
|
||||
|
||||
数值序列为 `[0,1,6,10]`,共有 3 个内部间隙,至少切一刀,所以合法方案共 $2^3-1=7$ 个。
|
||||
|
||||
| 分段方案 | 各段平均值 | 极差 |
|
||||
|---|---|---|
|
||||
| `[0] \| [1,6,10]` | 0、17/3 | 17/3 |
|
||||
| `[0,1] \| [6,10]` | 1/2、8 | 15/2 |
|
||||
| `[0,1,6] \| [10]` | 7/3、10 | 23/3 |
|
||||
| `[0] \| [1] \| [6,10]` | 0、1、8 | 8 |
|
||||
| `[0] \| [1,6] \| [10]` | 0、7/2、10 | 10 |
|
||||
| `[0,1] \| [6] \| [10]` | 1/2、6、10 | 19/2 |
|
||||
| `[0] \| [1] \| [6] \| [10]` | 0、1、6、10 | 10 |
|
||||
|
||||
最小极差为 $17/3$,保留六位小数输出 `5.666667`。
|
||||
|
||||
#### 3. 补全后的完整程序
|
||||
|
||||
```cpp
|
||||
#include <algorithm>
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
constexpr int N = 25;
|
||||
int n, a[N];
|
||||
char s[N];
|
||||
double ans = 1e100;
|
||||
|
||||
int value(char c) {
|
||||
return c - (c < 'A' ? '0' : 'A' - 10);
|
||||
}
|
||||
|
||||
void split(int l, int cnt, double mnb, double mxb) {
|
||||
if (l > n) {
|
||||
if (cnt == 0) return;
|
||||
ans = min(ans, mxb - mnb);
|
||||
return;
|
||||
}
|
||||
|
||||
int sum = 0;
|
||||
for (int r = l; r <= n; ++r) {
|
||||
sum += a[r];
|
||||
double nwb = sum * 1.0 / (r - l + 1);
|
||||
split(r + 1, cnt + (r < n),
|
||||
min(mnb, nwb), max(mxb, nwb));
|
||||
}
|
||||
}
|
||||
|
||||
int main() {
|
||||
cin >> n >> (s + 1);
|
||||
for (int i = 1; i <= n; ++i)
|
||||
a[i] = value(s[i]);
|
||||
split(1, 0, 1e100, -1e100);
|
||||
cout << fixed << setprecision(6) << ans;
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
代码按常见竞赛 C++14/C++17 环境书写;读取 `s+1` 的语句含义与原题一致。原文件在输出语句处结束了代码展示,这里补齐了 `return 0;` 和主函数结束括号。
|
||||
|
||||
#### 4. 为什么枚举不会漏解
|
||||
|
||||
任意一个合法连续分段方案,都唯一确定第一段右端点、第二段右端点,直到最后一段右端点 n。递归在每层遍历所有可能的右端点,因此每个方案都能被访问一次,也不会重复。
|
||||
|
||||
n-1 个内部间隙各有“切”或“不切”两种选择,共 $2^{n-1}$ 个完整方案,排除一刀不切后为 $2^{n-1}-1$ 个合法方案。代码通过累计 sum 和维护最值,使每条递归边的工作量为常数,总时间复杂度为 $O(2^n)$,递归栈空间为 $O(n)$。n≤20 时适合直接枚举。
|
||||
|
||||
## 五、复习重点
|
||||
|
||||
| 知识点 | 对应题号 | 需要掌握的结论或方法 |
|
||||
|---|---|---|
|
||||
| 整数范围与浮点精度 | 1 | 存得下某数量级,不代表能精确表示每个整数 |
|
||||
| 进制与数位权重 | 2、16~21、34~38 | 除 2 读取二进制位;移动数位改变位权 |
|
||||
| 栈、树、图 | 4、5、8、15 | 后进先出、完全二叉树编号、BFS 队列顺序、握手定理 |
|
||||
| 递推与计数 | 6、7、9 | 容斥、按最后一步分类、最大公约数化简 |
|
||||
| 最优性判断 | 10、14 | 贪心需要依据;距离和最小取中位数 |
|
||||
| 数组与指针 | 11 | 指针偏移对应数组下标,注意赋值顺序 |
|
||||
| 二分与前缀和 | 12、13 | 区间反复减半;原项等于相邻前缀和之差 |
|
||||
| 高精度加法 | 22~27 | 低位先算、进位条件、固定输出长度 |
|
||||
| DFS 与剪枝 | 28~33 | 区分递归访问顺序和数值顺序,跟踪提前返回 |
|
||||
| 连续分段枚举 | 39~43 | 状态含义、内部切分计数、浮点除法、最值初值 |
|
||||
|
||||
做程序题时,先确定变量含义与循环不变量,再手算一个小例子;看到“一定”“所有”等断言时,优先检查 0、最小输入、无进位和边界恰好相等等情形。
|
||||
Binary file not shown.
Reference in new issue
Block a user