CSP-J 2024 选择题与完善程序训练

答案版
考试时间:7月10日下午
题型:单项选择题 / 完善程序题
题量:25题
满分:100分
用途:课堂讲评 / LearnDash 嵌入
一、单项选择题
单项选择题每题2分,完善程序题每题7分。点击按钮显示答案和简短解析。
1. 32 位 int 类型的存储范围是?
A. -2147483647 ~ +2147483647
B. -2147483647 ~ +2147483648
C. -2147483648 ~ +2147483647
D. -2147483648 ~ +2147483648
答案:C。32 位有符号 int 通常范围为 -2^31 到 2^31-1。
2. 计算 (148 − 10102) × D16 − 11012 的结果,并选择十进制值。
A. 13
B. 14
C. 15
D. 16
答案:A。148 = 12,10102 = 10,D16 = 13,11012 = 13,所以 (12 − 10) × 13 − 13 = 13。
3. 10 名员工分属 4、3、3 三个部门,选 4 人且每部门至少 1 人,有多少种选择?
A. 120
B. 126
C. 132
D. 238
答案:B。分配为 2,1,1:A 部门选2人为 C(4,2)*3*3=54,B 部门选2人为 4*C(3,2)*3=36,C 部门选2人为 4*3*C(3,2)=36,总计126。
4. 以下哪个序列对应数字 0 至 7 的 4 位二进制格雷码?
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
答案:D。标准二进制反射格雷码 0 到 7 依次为该序列。
5. 1MB 是多少二进制位 bit?
A. 1000000
B. 1048576
C. 8000000
D. 8388608
答案:D。1MB=1024*1024 字节,每字节8 bit,共 8388608 bit。
6. 以下哪个不是 C++ 中的基本数据类型?
A. int
B. float
C. struct
D. char
答案:C。struct 是用于定义结构体类型的关键字,不是基本数据类型。
7. 以下哪个不是 C++ 中的循环语句?
A. for
B. while
C. do-while
D. repeat-until
答案:D。C++ 没有 repeat-until 循环语句。
8. 在 C/C++ 中,(char)('a' + 13) 与下面哪个值相等?
A. 'm'
B. 'n'
C. 'z'
D. 'l'
答案:B。'a' 后移 13 位为 'n'。
9. 1000 个元素的有序表二分查找最多比较几次?
A. 25
B. 10
C. 7
D. 1
答案:B。2^10=1024,最多约 10 次比较。
10. 下面哪一个不是操作系统名字?
A. Notepad
B. Linux
C. Windows
D. macOS
答案:A。Notepad 是文本编辑器。
11. 在无向图中,所有顶点的度数之和等于?
A. 图的边数
B. 图的边数的两倍
C. 图的顶点数
D. 图的顶点数的两倍
答案:B。每条无向边对度数总和贡献 2。
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,B,E,F,G,A,C]
答案:A。根为 A,左子树 B 的后序为 D,E,B,右子树 C 的后序为 F,G,C,最后访问 A。
13. 入栈 1 2 3 4 5 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
答案:D。输出 5 后,2 已在栈底且 4 在其上方,不可能先出 2 再出 4。
14. 5 个男生和 3 个女生站成一排,3 个女生必须相邻,有多少种排列?
A. 4320 种
B. 5040 种
C. 3600 种
D. 2880 种
答案:A。把 3 个女生看作一组,与 5 个男生共 6 个单位排列,6!*3!=4320。
15. 编译器的主要作用是什么?
A. 直接执行源代码
B. 将源代码转换为机器代码
C. 进行代码调试
D. 管理程序运行时的内存
答案:B。编译器主要把高级语言源代码翻译成目标代码或机器代码。
三、完善程序

一、字符串解码

“行程长度编码”(Run-Length Encoding)是一种无损压缩算法,常用于压缩重复字符较多的数据,以减少存储空间。假设原始字符串不包含数字字符,压缩规则如下:
以下程序实现读取压缩字符串并输出其原始的、解压后的形式,试补全程序。
字符串解码
cpp
1#include <cctype>
2#include <iostream>
3#include <string>
4using namespace std;
5
6int main() {
7 string z;
8 cin >> z;
9 string s = "";
10
11 for (int i = 0; i < z.length(); ) {
12 char ch = z[i];
13
14 if (① && isdigit(z[i + 1])) {
15 i++;
16 int count = 0;
17 while (i < z.length() && isdigit(z[i])) {
18 count = ②;
19 i++;
20 }
21 for (int j = 0; j < ③; ++j) {
22 s += ch;
23 }
24 } else {
25 s += ④;
26 ⑤;
27 }
28 }
29
30 cout << s << endl;
31 return 0;
32}

程序功能

程序实现字符串解码:输入一个由字母和数字组成的编码串,将“字符 + 数字”还原为重复若干次的字符,并输出原字符串。

例如,输入 a12b3,输出 aaaaaaaaaaaabbb

执行过程

关键语句

z[i] - '0' 将数字字符转换为对应整数;i++ 负责跳过已经处理的字符或数字,避免重复处理。

16. ①处应填?
A. i < z.length()
B. i - 1 >= 0
C. i + 1 < z.length()
D. isdigit(z[i])
答案:C。访问 z[i+1] 前必须保证 i+1 没有越界。
17. ②处应填?
A. count + (z[i]-'0')
B. count * 10 + (z[i]-'0')
C. z[i] - '0'
D. count + 1
答案:B。连续数字可能有多位,需要按十进制逐位累加。
18. ③处应填?
A. count - 1
B. count
C. 10
D. z[i] - '8'
答案:B。字符需要输出 count 次。
19. ④处应填?
A. z[i + 1]
B. ch
C. z.back()
D. (char)z[i] + 1
答案:B。没有数字计数时,该字符只出现一次,加入当前字符 ch。
20. ⑤处应填?
A. i--
B. i = i + 2
C. i++
D. //不执行任何操作
答案:C。处理完单个字符后,需要移动到下一个位置。

二、精明与糊涂

N 个人,分为两类:

已知精明人严格占据多数,即如果精明人有 k 个,则满足 k > N / 2。你只能通过函数 query(i, j) 让第 i 个人判断第 j 个人:返回 true 表示判断结果为“精明人”;返回 false 表示判断结果为“糊涂人”。你的目标是通过互相判断,找出至少一个百分之百能确定的精明人。同时,你无需关心 query(i, j) 的内部实现。

以下程序利用“精明人占多数”的优势,通过“消除”过程让人们互相判断并进行抵消,经过若干轮抵消后,最终留下的候选者必然属于多数派,即精明人。

例如,假设有三个人 012。如果 01 是糊涂人,而 1 也说 0 是糊涂人,则 01 至少有一个是糊涂人。程序将同时淘汰 01。由于三人里至少有两个精明人,我们确定 2 是精明人。

精明与糊涂
cpp
1#include <iostream>
2#include <vector>
3using namespace std;
4
5int N;
6bool query(int i, int j);
7
8int main() {
9 cin >> N;
10
11 int candidate = 0;
12 int count = ①;
13
14 for (int i = 1; i < N; ++i) {
15 if (②) {
16 candidate = i;
17 count = 1;
18 } else {
19 if (③) {
20 ④;
21 } else {
22 count++;
23 }
24 }
25 }
26
27 cout << ⑤ << endl;
28 return 0;
29}

程序功能

程序从一组“精明人”和“糊涂人”中找出一个确定的精明人编号。核心方法是多数派消除:不同阵营的两个人可以互相抵消,最终留下的候选人再进行验证。

算法过程

关键语句

count == 0 表示当前候选已没有未抵消的支持;query(candidate, i) == false && query(i, candidate) == false 表示两人互相认为对方糊涂,可以配对抵消;candidate = i 用于更新候选人。

这种方法只需一次扫描,时间复杂度为 O(N),额外空间复杂度为 O(1)

21. ①处应填?
A. 0
B. 1
C. N
D. -1
答案:B。初始候选人为 0,当前候选计数应从 1 开始。
22. ②处应填?
A. count < 0
B. count == 1
C. count == 0
D. query(candidate, i) == false
答案:C。当当前候选被抵消完,计数为 0 时,选择新的候选人。
23. ③处应填?
A. query(candidate, i) == false
B. query(i, candidate) == true
C. query(candidate, i) == false && query(i, candidate) == false
D. query(candidate, i) == false || query(i, candidate) == false
答案:C。两人互相判断对方为糊涂人时,至少一方是糊涂人,可以与候选计数抵消。
24. ④处应填?
A. count--
B. break
C. count++
D. candidate = i
答案:A。发生抵消时,当前候选阵营的计数减少 1。
25. ⑤处应填?
A. N - 1
B. count
C. candidate
D. 0
答案:C。最终留下的候选者就是要输出的精明人编号。