#KGT0010. CSP-S 第一轮初赛模拟试卷 · 第 3 套
CSP-S 第一轮初赛模拟试卷 · 第 3 套
CSP-S 第一轮(初赛)模拟试卷(第 3 套)
满分 100 分 时间 100 分钟 语言 C++
注意事项:
- 本卷共三大题,43 小题。
- 单项选择题共 15 题,每题 2 分,共 30 分。
- 阅读程序共 3 题,40 分(判断题每题 2 分;选择题每题 2 分,其中第 21、27、32、33 题每题 3 分)。
- 完善程序共 2 题,30 分(每题 5 空,每空 3 分)。
一、单项选择题(共 15 题,每题 2 分,共 30 分;每题有且仅有一个正确选项)
1. 设 a 为 32 位有符号整数,若表达式 a & (a - 1) 的值为 0,则( )
{{ select(1) }}
- a 一定是 2 的正整数次幂
- a 是 0 或 2 的幂
- a 一定是奇数
- a 一定是 0
2. 某字符采用 UTF-8 编码,其字节序列为 E4 B8 AD(十六进制,共 3 个字节)。则该字符的 Unicode 码点值(十进制)是( )
{{ select(2) }}
- 19968
- 20013
- 21475
- 25014
3. 某存储设备标称容量为 8 GB(此处 1 GB = 10⁹ 字节),则其实际容量最接近( )
{{ select(3) }}
- 8.59 GiB
- 7.45 GiB
- 8.00 GiB
- 8.39 GiB
4. 下列排序算法中,最坏情况下时间复杂度为 O(n log n) 的是( )
{{ select(4) }}
- 快速排序
- 插入排序
- 堆排序
- 冒泡排序
5. 已知递推式 T(n) = T(n−1) + n,T(1) = 1,则 T(n) 的渐近时间复杂度为( )
{{ select(5) }}
- O(n)
- O(n log n)
- O(n²)
- O(log n)
6. 用数组实现循环队列,容量为 m,front 指向队首元素,rear 指向队尾元素的下一个位置。则当前队列中元素的个数为( )
{{ select(6) }}
rear - front(rear - front + m) % m(front - rear + m) % mrear - front + 1
7. 具有 n 个结点的二叉树采用二叉链表(每个结点含 left、right 两个指针)存储,则所有结点中空指针域的总个数为( )
{{ select(7) }}
- n
- n − 1
- n + 1
- 2n
8. 由 4 个互不相同的结点可以构成( )棵形态不同的二叉树
{{ select(8) }}
- 10
- 12
- 14
- 16
9. 对序列 5, 3, 8, 1, 9, 2 进行冒泡排序(升序,从前往后相邻比较交换),第一趟排序结束后的序列为( )
{{ select(9) }}
- 3, 5, 1, 8, 2, 9
- 3, 5, 8, 1, 2, 9
- 3, 1, 5, 8, 2, 9
- 1, 3, 5, 2, 8, 9
10. 定义 f(0) = 0,f(1) = 1,f(n) = f(n−1) + f(n−2)(n ≥ 2),则 f(10) =( )
{{ select(10) }}
- 34
- 55
- 89
- 144
11. gcd(2024, 748) =( )
{{ select(11) }}
- 22
- 44
- 88
- 11
12. 将 10 个完全相同的小球放入 3 个不同的盒子中,允许盒子为空,共有( )种不同的放法
{{ select(12) }}
- 66
- 120
- 220
- 45
13. 在计算复杂性理论中,若一个问题可以在多项式时间内验证某个候选解的正确性,则这个问题属于( )
{{ select(13) }}
- P 类
- NP 类
- NPC 类
- 不可判定问题
14. IEEE 754 单精度浮点数共占 32 位,其中指数(阶码)部分占( )位
{{ select(14) }}
- 7
- 8
- 11
- 23
15. 字符 a、b、c、d、e 的出现频率分别为 5、9、12、13、16。用哈夫曼(Huffman)编码对它们编码,则字符 a 的编码长度为( )
{{ select(15) }}
- 2
- 3
- 4
- 5
二、阅读程序(共 3 题,40 分)
说明: 每题给出一段完整可编译的 C++ 程序。判断题(每题 2 分):正确的选 T,错误的选 F;选择题(每题 2 分,其中标注「3 分」的每题 3 分):每题有且仅有一个正确选项。
第 1 题(判断题 16–18,选择题 19–21)
#include <iostream>
using namespace std;
int popcount(int x) {
int c = 0;
while (x) { c++; x &= x - 1; }
return c;
}
int gray(int x) { return x ^ (x >> 1); }
int revbits(int x) {
int r = 0;
while (x) { r = (r << 1) | (x & 1); x >>= 1; }
return r;
}
int main() {
int n;
cin >> n;
cout << popcount(n) << " " << gray(n) << " " << revbits(n) << endl;
return 0;
}
判断题:
16. popcount(n) 返回的是 n 的二进制表示的位数(不含前导零)。( )
{{ select(16) }}
- 正确
- 错误
17. 对于任意正整数 n,gray(n) 与 n 的二进制位数相同。( )
{{ select(17) }}
- 正确
- 错误
18. 对于任意正整数 n,revbits(n) 都是奇数。( )
{{ select(18) }}
- 正确
- 错误
选择题:
19. 若输入为 6,程序输出为( )
{{ select(19) }}
2 5 32 3 53 5 22 5 6
20. 若输入为 10,程序输出为( )
{{ select(20) }}
2 5 52 15 52 5 103 15 5
21. (3 分)若输入为 2024,程序输出的第一个数是( )
{{ select(21) }}
- 5
- 6
- 7
- 8
第 2 题(判断题 22–24,选择题 25–27)
#include <iostream>
using namespace std;
long long f[50][50];
long long c(int n, int k) {
if (k < 0 || k > n) return 0;
if (k == 0 || k == n) return 1;
if (f[n][k]) return f[n][k];
return f[n][k] = c(n - 1, k - 1) + c(n - 1, k);
}
int main() {
int n;
cin >> n;
long long s = 0;
for (int k = 0; k <= n; k++) s += c(n, k);
cout << s << endl;
return 0;
}
判断题:
22. 该程序输出的结果等于 2^n − 1。( )
{{ select(22) }}
- 正确
- 错误
23. 函数 c(n, k) 返回的是组合数 C(n, k)。( )
{{ select(23) }}
- 正确
- 错误
24. 若删去 if (f[n][k]) return f[n][k]; 这一行,程序输出的结果不变,但运行时间会显著增加。( )
{{ select(24) }}
- 正确
- 错误
选择题:
25. 若输入为 10,程序输出为( )
{{ select(25) }}
- 512
- 1024
- 2048
- 3628800
26. 若输入为 30,程序输出为( )
{{ select(26) }}
- 536870912
- 1073741824
- 2147483648
- 43589145600
27. (3 分)在保留记忆化(memoization)的情况下,该程序的时间复杂度为( )
{{ select(27) }}
- O(n)
- O(n log n)
- O(n²)
- O(2ⁿ)
第 3 题(判断题 28–30,选择题 31–33)
#include <iostream>
#include <queue>
#include <algorithm>
using namespace std;
int n, m, a[105][105], vis[105][105];
int dx[4] = {0, 0, 1, -1};
int dy[4] = {1, -1, 0, 0};
int bfs(int x, int y) {
queue<pair<int,int>> q;
q.push({x, y});
vis[x][y] = 1;
int sz = 0;
while (!q.empty()) {
pair<int,int> p = q.front();
q.pop();
sz++;
for (int d = 0; d < 4; d++) {
int nx = p.first + dx[d], ny = p.second + dy[d];
if (nx >= 1 && nx <= n && ny >= 1 && ny <= m && !vis[nx][ny] && a[nx][ny]) {
vis[nx][ny] = 1;
q.push({nx, ny});
}
}
}
return sz;
}
int main() {
cin >> n >> m;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++)
cin >> a[i][j];
int cnt = 0, mx = 0;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++)
if (a[i][j] && !vis[i][j]) {
int s = bfs(i, j);
cnt++;
mx = max(mx, s);
}
cout << cnt << " " << mx << endl;
return 0;
}
判断题:
28. 程序输出的第二个数等于网格中由相邻(上、下、左、右)的 1 构成的连通块个数。( )
{{ select(28) }}
- 正确
- 错误
29. 若把 queue<pair<int,int>> 换成栈(stack,入队改为入栈、出队改为出栈),程序输出的两个数都不变。( )
{{ select(29) }}
- 正确
- 错误
30. 该程序的时间复杂度为 O(n × m)。( )
{{ select(30) }}
- 正确
- 错误
选择题:
31. 若输入为:
4 5
1 1 0 0 1
0 1 0 1 1
1 0 0 0 1
1 1 0 1 0
则程序输出为( )
{{ select(31) }}
3 34 44 55 4
32. (3 分)若输入为:
1 1
0
则程序输出为( )
{{ select(32) }}
0 00 11 01 1
33. (3 分)函数 bfs(x, y) 的返回值表示( )
{{ select(33) }}
- 从 (x, y) 出发 BFS 访问的层数
- 包含 (x, y) 的连通块中值为 1 的格子数(面积)
- 网格中 1 的总个数
- 距离 (x, y) 最远的 1 的距离
三、完善程序(共 2 题,30 分;每题 5 空,每空 3 分)
第 1 题(欧拉筛求质数个数,第 34–38 题)
题目: 以下程序使用欧拉筛(线性筛)在 O(n) 时间内筛出不超过 n 的所有质数,并输出质数的个数。该算法的关键在于保证每个合数只被它的最小质因数筛掉一次,从而把复杂度降到 O(n)。请补全下面的程序。
#include <iostream>
using namespace std;
const int N = 1000000;
int primes[N], cnt;
bool notPrime[N]; // notPrime[i] 为 true 表示 i 是合数
void sieve(int n) {
for (int i = 2; i <= n; i++) {
if (!notPrime[i]) primes[①] = i;
for (int j = 0; j < ② && i * primes[j] <= ③; j++) {
notPrime[④] = true;
if (i % primes[j] == 0) ⑤;
}
}
}
int main() {
int n;
cin >> n;
sieve(n);
cout << cnt << endl;
return 0;
}
34. ① 处应填( )
{{ select(34) }}
cntcnt++++cntcnt - 1
35. ② 处应填( )
{{ select(35) }}
j < nj < cntj <= cntj < i
36. ③ 处应填( )
{{ select(36) }}
niprimes[j]N
37. ④ 处应填( )
{{ select(37) }}
i * primes[j]i + primes[j]iprimes[j]
38. ⑤ 处应填( )
{{ select(38) }}
continuebreakreturnj++
第 2 题(归并排序求逆序对,第 39–43 题)
题目: 以下程序使用归并排序(分治法)在 O(n log n) 时间内计算一个长度为 n 的序列的逆序对个数。逆序对是指满足 i < j 且 a[i] > a[j] 的二元组 (i, j)。请补全下面的程序。
#include <iostream>
using namespace std;
const int N = 100000;
int a[N], tmp[N];
long long ans;
void merge_sort(int l, int r) {
if (l >= r) return;
int mid = (l + r) >> 1;
merge_sort(l, mid);
merge_sort(mid + 1, r);
int i = l, j = mid + 1, k = ①;
while (i <= mid && j <= r) {
if (a[i] <= a[j]) tmp[k++] = a[②];
else { tmp[k++] = a[j++]; ans += ③; }
}
while (i <= mid) tmp[k++] = a[i++];
while (j <= r) tmp[k++] = a[j++];
for (int t = l; t <= r; t++) a[t] = ④;
}
int main() {
int n;
cin >> n;
for (int i = 1; i <= n; i++) cin >> a[i];
merge_sort(1, n);
cout << ⑤ << endl;
return 0;
}
39. ① 处应填( )
{{ select(39) }}
0lmidr
40. ② 处应填( )
{{ select(40) }}
i++j++ij
41. ③ 处应填( )
{{ select(41) }}
j - midmid - i + 1r - j + 1i - mid
42. ④ 处应填( )
{{ select(42) }}
a[t]tmp[t]tmp[t - l]tmp[k]
43. ⑤ 处应填( )
{{ select(43) }}
ansa[1]a[n]tmp[n]
—— 试卷结束 ——
冀公网安备13098402000493号