GESP 客观题评测系统

试卷解析 · 理解每一步

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

CSPJ-2022-R1-Mock-Luogu

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

一、单项选择题

第 1 题(单选题,2 分)

(1047)8=(1047)_8=( )。

A.
(1011011101)2(1011011101)_2
B.
(11010)5(11010)_5
C.
(20213)4(20213)_4
D.
(308)16(308)_{16}

正确答案C

解析详情
答案 C进制转换
思路与推导
  1. (1047)8=1×83+4×82+7=775(1047)_8=1×8^3+4×8^2+7=775,而 (20213)4=2×44+2×42+4+3=775(20213)_4=2×4^4+2×4^2+4+3=775,故选 C。

第 2 题(单选题,2 分)

若逻辑变量 A、C 为真,B、D 为假,以下逻辑表达式的值为假的是( )。

A.
(B∨C∨D)∨D∧A(B\lor C\lor D)\lor D\land A
B.
((¬A∧B)∨C)∧¬B((\lnot A\land B)\lor C)\land\lnot B
C.
(A∧B)∨¬(C∧D∨¬A)(A\land B)\lor\lnot(C\land D\lor\lnot A)
D.
A∧(D∨¬C)∧BA\land(D\lor\lnot C)\land B

正确答案D

解析详情
答案 D逻辑表达式
思路与推导
  1. 代入 A=C=真、B=D=假A=C=真、B=D=假,D 式含有合取项 BB,整体必为假;其余三式均为真。

第 3 题(单选题,2 分)

小恺编写如下朴素递归函数计算斐波那契数列第 nn 项对 10000 的余数。在 128 MB、1 秒限制下运行 `f(12345)`,最可能首先发生什么问题?

int f(int x) {
    if (x <= 2) return 1;
    int ans = f(x - 1) + f(x - 2);
    ans %= 10000;
    return ans;
}
A.
运行时间超时
B.
栈溢出
C.
访问无效内存
D.
返回错误的答案

正确答案A

解析详情
答案 A递归复杂度
思路与推导
  1. 朴素斐波那契递归会重复计算,调用次数按指数级增长;`f(12345)` 远超 1 秒,通常先超时。

第 4 题(单选题,2 分)

表达式 `a+b*(c-d)/e-f` 的后缀表达式为( )。

A.
`-+a/*b-c-cdef`
B.
`abcd-*e/+f-`
C.
`+ab*-cd/e-f`
D.
`f-e/d-d*b+a`

正确答案B

解析详情
答案 B后缀表达式
思路与推导
  1. 先将 `(c-d)` 写为 `cd-`,再依次完成乘、除、加、减,得到 `abcd-*e/+f-`。

第 5 题(单选题,2 分)

一段时长 4 分钟、每秒 10 帧、每帧 2048×11522048\times1152 像素、32 位真彩色且画面未压缩、没有音频的视频,约需多少存储空间?

A.
21 GiB
B.
27 GiB
C.
168 GiB
D.
2 GiB

正确答案A

解析详情
答案 A图像存储
思路与推导
  1. 240×10×2048×1152×32/8240×10×2048×1152×32/8 字节约为 21.1 GiB,因此选 21 GiB。

第 6 题(单选题,2 分)

下图二叉树的后序遍历是( )。

二叉树示意图
A.
`ABDEFC`
B.
`DBEFAC`
C.
`DFEBCA`
D.
`ABCDEF`

正确答案C

解析详情
答案 C二叉树遍历
思路与推导
  1. 后序顺序是左子树、右子树、根:B 子树为 `DFEB`,C 子树为 `C`,最后访问 A,得到 `DFEBCA`。

第 7 题(单选题,2 分)

五个本质不同的点在没有重边或自环时,能组成多少个不同的无向图?

A.
10
B.
1024
C.
15
D.
120

正确答案B

解析详情
答案 B图的计数
思路与推导
  1. 5 个标号点共有 inom{5}{2}=10 条可能的无向边,每条边独立选择有或无,共 210=10242^{10}=1024 个图。

第 8 题(单选题,2 分)

元素 `a,b,c,d,e,f` 依次入栈,下列不合法的出栈序列为( )。

A.
`d,c,b,e,f,a`
B.
`f,e,d,c,b,a`
C.
`c,d,f,e,b,a`
D.
`e,d,b,a,f,c`

正确答案D

解析详情
答案 D栈序列
思路与推导
  1. D 中弹出 `e,d` 后,栈内从顶到底为 `c,b,a`;不可能越过 `c` 先弹出 `b`,故不合法。

第 9 题(单选题,2 分)

同时扔出 3 枚完全相同的六面骰子,将点数排序后有多少种不同结果?

A.
208
B.
56
C.
216
D.
120

正确答案B

解析详情
答案 B组合计数
思路与推导
  1. 排序后的三个点数等价于从 1~6 中可重复选 3 个,方案数为 inom{6+3-1}{3}=56。

第 10 题(单选题,2 分)

从磁盘文件输入很大的二维数组时,按行读与按列读相比,在输入效率上( )。

A.
没有区别
B.
按行读更高
C.
按列读更高
D.
取决于数组的存储方式

正确答案D

解析详情
答案 D存储布局
思路与推导
  1. 访问效率取决于数组采用行优先还是列优先存储;连续访问内存通常能更好利用缓存和磁盘缓冲。

第 11 题(单选题,2 分)

不考虑稳定性,下列排序方法中平均时间复杂度最大的是( )。

A.
插入排序
B.
希尔排序
C.
归并排序
D.
快速排序

正确答案A

解析详情
答案 A排序复杂度
思路与推导
  1. 插入排序平均时间复杂度为 O(n2)O(n^2);归并和快速排序平均为 O(nlogn)O(nlog n),希尔排序通常也优于直接插入排序。

第 12 题(单选题,2 分)

将 `12,23,-1,19,117,-103,79,602` 按从大到小排列,每次可交换任意两个元素,最少需交换几次?

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

正确答案B

解析详情
答案 B置换最少交换
思路与推导
  1. 把当前位置到目标降序位置的映射分解成环,8 个元素形成 3 个环,最少交换数为 8−3=58-3=5。

第 13 题(单选题,2 分)

3 名男生和 3 名女生围成一圈,同性不相邻;旋转可重合视为同一种方案,共有多少种方案?

A.
18
B.
15
C.
12
D.
9

正确答案C

解析详情
答案 C圆排列
思路与推导
  1. 先固定 3 名男生的圆排列,有 (3−1)!=2(3-1)!=2 种;3 名女生放入三个间隙有 3!=63!=6 种,共 12 种。

第 14 题(单选题,2 分)

以下关于 C++ 字符串的说法,错误的是( )。

A.
定义 `string` 时不需预先确定最大长度。
B.
字符数组和 `string` 可以相互转化。
C.
定义 `char a[100]` 并从键盘读入字符串时,字符串长度不能超过 99。
D.
定义 `string s` 后,获得其长度的方式就是 `strlen(s)`。

正确答案D

解析详情
答案 DC++ 字符串
思路与推导
  1. `strlen` 接收 C 风格字符指针,不能直接传入 `std::string`;应使用 `s.size()` 或 `s.length()`。

第 15 题(单选题,2 分)

中国计算机协会成立于( )年。

A.
1961
B.
1962
C.
1971
D.
1972

正确答案B

解析详情
答案 B计算机组织历史
思路与推导
  1. 按原卷答案,中国计算机协会成立年份为 1962 年,因此选择 B。

二、阅读程序(1)

 1 | #include <iostream>
 2 | using namespace std;
 3 | const int MAXN = 1000050;
 4 | int n, a[MAXN], a1[MAXN], b[MAXN], lim;
 5 | void solve1() {
 6 |     for (int i = 1; i <= n; i++)
 7 |         b[a[i]]++; //①
 8 |     for (int i = 1; i <= lim; i++) {
 9 |         if (b[i]) //②
10 |             cout << i << " ";
11 |     }
12 |     cout << endl;
13 | }
14 | void solve2() {
15 |     int cnt = 0, flag;
16 |     for (int i = 1; i <= n; i++) {
17 |         flag = false;
18 |         for (int j = 1; j <= n - 1; j++) {
19 |             if (a[j] > a[j + 1]) {
20 |                 swap(a[j], a[j + 1]);
21 |                 cnt++;
22 |                 flag = true;
23 |             }
24 |         }
25 |         //if (flag==false)
26 |         // break;
27 |     }
28 |     for (int i = 1; i <= n; i++)
29 |         cout << a[i] << " ";
30 |     cout << endl;
31 | }
32 | int main() {
33 |     cin >> n;
34 |     for (int i = 1; i <= n; i++) {
35 |         cin >> a[i];
36 |         a1[i] = a[i]; //③
37 |         lim = max(a[i], lim); //④
38 |     }
39 |     solve1();
40 |     for (int i = 1; i <= n; i++)
41 |         a[i] = a1[i];
42 |     solve2();
43 |     return 0;
44 | }

已知 1≤n,ai≤1061\le n,a_i\le10^6。完成下列题目。

第 16 题(判断题,2 分)

`solve2` 实现了选择排序。( )

正确答案错误

解析详情
答案 错误冒泡排序
思路与推导
  1. `solve2` 反复比较并交换相邻逆序元素,实现的是冒泡排序,不是选择排序。

第 17 题(判断题,2 分)

`solve1` 的时间复杂度为 O(n+V)O(n+V),其中 VV 是 aia_i 的最大值。( )

正确答案正确

解析详情
答案 正确计数排序复杂度
思路与推导
  1. 统计 nn 个元素需 O(n)O(n),再扫描到最大值 VV 需 O(V)O(V),总复杂度为 O(n+V)O(n+V)。

第 18 题(判断题,2 分)

输入 `7 2 3 5 7 1 4 6` 时,`solve2` 中的 `cnt` 最终为 9。( )

正确答案错误

解析详情
答案 错误逆序对与交换次数
思路与推导
  1. 冒泡排序的交换次数等于逆序对数;序列 `2,3,5,7,1,4,6` 共有 7 个逆序对,不是 9。

第 19 题(判断题,2 分)

移除 `solve2` 中注释行的双斜杠,不会影响输出结果。( )

正确答案正确

解析详情
答案 正确冒泡排序优化
思路与推导
  1. 取消注释后,某一轮没有交换时提前退出;此时数组已经有序,所以最终输出不变。

第 20 题(单选题,3 分)

哪组 n=8n=8 的数据会使 `solve1` 与 `solve2` 输出不同?

A.
`1 10 100 1000 10000 888 8888 88888`
B.
`6321 158987 16305 68486 50556 847 156505 15610`
C.
`777 888 999 888 777 888 999 666`
D.
`999993 999994 999995 999996 999997 999998 999999 1000000`

正确答案C

解析详情
答案 C计数输出
思路与推导
  1. C 中存在重复值,`solve1` 的 `if (b[i])` 每个不同值只输出一次,而 `solve2` 会保留并输出所有重复元素。

第 21 题(单选题,3 分)

若要使 `solve1` 和 `solve2` 输出相同,应修改哪一处?

A.
①
B.
②
C.
③
D.
④

正确答案B

解析详情
答案 B计数排序修正
思路与推导
  1. 应修改 ②,使每个值按 `b[i]` 的次数重复输出,例如用循环消耗计数;这样才能与冒泡排序结果一致。

二、阅读程序(2)

 1 | #include <cstdio>
 2 | #include <cstring>
 3 |
 4 | const int maxn = 1003;
 5 |
 6 | int type, n, m;
 7 | char s[maxn], t[maxn];
 8 |
 9 | int main() {
10 |     scanf("%d %s %s", &type, t, s);
11 |     n = strlen(s); m = strlen(t);
12 |     if (type < 2) {
13 |         for (int i = 0; i < m; ++i) s[i] = t[i];
14 |     } else if (type == 2) {
15 |         strcpy(s, t);
16 |         // 提示:如果此时调用 printf("%s\n", s),则本次输出结果为整个 t 字符串和换行,没有其他字符。
17 |     } else {
18 |         for (int i = 0; i < m; i += 4) {
19 |             unsigned int code = 0, pos = i;
20 |             for (int j = 1; pos < i+4; j*=100, ++pos) {
21 |                 if (pos == m) break;
22 |                 code += t[pos] * j;
23 |             }
24 |             pos = i;
25 |             while (code != 0) {
26 |                 s[pos++] = code % 100;
27 |                 code /= 100;
28 |             }
29 |         }
30 |     }
31 |     for (int i = 0; i < n; ++i) printf("%c", s[i]);
32 |     printf("\n");
33 | }

输入保证 `t` 不长于 `s`,两字符串仅含大小写字母且非空,`type=1,2,3`。

第 22 题(判断题,2 分)

将程序中所有 `<` 改为 `!=`,对所有合法输入的输出不变。( )

正确答案错误

解析详情
答案 错误循环条件
思路与推导
  1. 把所有 `<` 改为 `!=` 后,`type < 2` 变成 `type != 2`,会把 `type=3` 错误地送入第一分支,输出会改变。

第 23 题(判断题,2 分)

输入 `1 xyz abcd` 时输出 `xyzd`。( )

正确答案正确

解析详情
答案 正确字符数组覆盖
思路与推导
  1. `type=1` 时把 `t` 的三个字符 `xyz` 写到 `s` 前三位,原来的第四个字符 `d` 保留,因此输出 `xyzd`。

第 24 题(判断题,2 分)

输入 `1 xyz abcd` 与 `2 xyz abcd` 的输出相同。( )

正确答案错误

解析详情
答案 错误strcpy 行为
思路与推导
  1. `type=2` 的 `strcpy` 会在 `xyz` 后写入 NUL 结束符,第 4 次 `%c` 输出空字符;这与 `type=1` 保留 `d` 的 `xyzd` 不同。

第 25 题(判断题,2 分)

将第 25~28 行 `while` 替换为判断条件和循环体不变的 `do-while`,输出一定不变。( )

正确答案正确

解析详情
答案 正确while 与 do-while
思路与推导
  1. 每个分组由非空字母组成,构造出的 `code` 一定非零,因此原 `while` 至少执行一次,改为 `do-while` 不改变结果。

第 26 题(单选题,2 分)

若第 13 行改为 `for (int i=0; i<strlen(t); ++i) s[i]=t[i];` 且 `type=1`,用 n,mn,m 分别表示 `s,t` 长度,时间复杂度为( )。

A.
Θ(n+m)\Theta(n+m)
B.
Θ(n+m2)\Theta(n+m^2)
C.
Θ(n2+m)\Theta(n^2+m)
D.
Θ(n2+m2)\Theta(n^2+m^2)

正确答案B

解析详情
答案 B字符串复杂度
思路与推导
  1. 循环条件每次调用 `strlen(t)`,单次扫描为 Theta(m)Theta(m),共执行 mm 次;加上最终输出 nn 个字符,总计 Theta(n+m2)Theta(n+m^2)。

第 27 题(单选题,3 分)

分别输入哪组选项中的两组数据,输出不同?

A.
`1 ab abc` 和 `3 ab abc`
B.
`1 AB ABC` 和 `3 AB ABC`
C.
`1 de fgh` 和 `3 de fgh`
D.
`1 DE FGH` 和 `3 DE FGH`

正确答案C

解析详情
答案 C字符编码模拟
思路与推导
  1. 小写 `d,e` 的 ASCII 值不小于 100,`type=3` 的百进制拆分会改变它们;`type=1` 直接复制,所以 C 的两次输出不同。

二、阅读程序(3)

 1 | #include <iostream>
 2 | using namespace std;
 3 |
 4 | const int INF = 1000000000;
 5 | #define Front 0
 6 | #define Back 1
 7 | #define Left 2
 8 | #define Right 3
 9 | #define Up 4
10 | #define Down 5
11 | int w[6], a[1003][1003];
12 | const int way1[] = {Up, Right, Down, Left};
13 | const int way2[] = {Up, Front, Down, Back};
14 | const int way3[] = {Left, Front, Right, Back};
15 | int get_max(int &a, int b) {
16 |     return a = max(a, b);
17 | }
18 | int right_rotate(int &u) {
19 |     for (int i = 0; i < 4; ++ i)
20 |         if (u == way1[i])
21 |             return u = way1[(i + 1) % 4];
22 |     return u;
23 | }
24 | int front_rotate(int &u) {
25 |     for (int i = 0; i < 4; ++ i)
26 |         if (u == way2[i])
27 |             return u = way2[(i + 1) % 4];
28 |     return u;
29 | }
30 | const int anchorX = Up;
31 | const int anchorY = Front;
32 | const int anchorZ = Right;
33 | int find_down(int u, int v) {
34 |     if (u == Down || u == Up) return anchorX ^ (u == Up);
35 |     if (v == Down || v == Up) return anchorY ^ (v == Up);
36 |     for (int i = 0; i < 4; ++ i)
37 |         if (u == way3[i])
38 |             return anchorZ ^ (v == way3[(i + 1) % 4]);
39 |     return -1;
40 | }
41 | int n, m, dp[1003][1003][6][6];
42 | int main() {
43 |     cin >> n >> m;
44 |     for (int i = 0; i < n; ++ i)
45 |         for (int j = 0; j < m; ++ j)
46 |             cin >> a[i][j];
47 |     for (int i = 0; i < 6; ++ i)
48 |         cin >> w[i];
49 |     for (int i = 0; i < n; ++ i)
50 |         for (int j = 0; j < m; ++ j)
51 |             for (int a = 0; a < 6; ++ a)
52 |                 for (int b = 0; b < 6; ++ b)
53 |                     dp[i][j][a][b] = -INF;
54 |     dp[0][0][anchorX][anchorY] = a[0][0] * w[Down];
55 |     for (int i = 0; i < n; ++ i)
56 |         for (int j = 0; j < m; ++ j)
57 |             for (int p = 0; p < 6; ++ p)
58 |                 for (int q = 0; q < 6; ++ q)
59 |                     if (dp[i][j][p][q] != -INF) {
60 |                         int x = dp[i][j][p][q];
61 |                         int u1 = p, v1 = q;
62 |                         right_rotate(u1);
63 |                         right_rotate(v1);
64 |                         get_max(dp[i][j + 1][u1][v1],
65 |                             x + w[find_down(u1, v1)] * a[i][j + 1]);
66 |                         int u2 = p, v2 = q;
67 |                         front_rotate(u2);
68 |                         front_rotate(v2);
69 |                         get_max(dp[i + 1][j][u2][v2],
70 |                             x + w[find_down(u2, v2)] * a[i + 1][j]);
71 |                     }
72 |     int ans = -INF;
73 |     for (int p = 0; p < 6; ++ p)
74 |         for (int q = 0; q < 6; ++ q)
75 |             ans = max(ans, dp[n - 1][m - 1][p][q]);
76 |     printf("%d\n", ans);
77 |     return 0;
78 | }

输入数据的绝对值均不超过 10310^3。

第 28 题(判断题,2 分)

存在合法输入,使某次 `find_down` 返回 -1。( )

正确答案错误

解析详情
答案 错误立方体朝向
思路与推导
  1. 程序只沿相邻格滚动立方体,`u,v` 始终表示两个互相垂直的面;第三个朝向可唯一确定,所以 `find_down` 不会走到 -1。

第 29 题(判断题,2 分)

程序时间复杂度为 Θ(n2m2)\Theta(n^2m^2)。( )

正确答案错误

解析详情
答案 错误动态规划复杂度
思路与推导
  1. 网格有 nmnm 个位置,每格枚举固定的 6×66×6 个朝向并做常数次转移,因此时间复杂度为 Theta(nm)Theta(nm)。

第 30 题(判断题,2 分)

对任意 u∈[0,6)u\in[0,6),先 `front_rotate` 再 `right_rotate` 与相反顺序的最终值相同。( )

正确答案错误

解析详情
答案 错误旋转不交换
思路与推导
  1. 两种旋转绕不同轴进行,一般不满足交换律;选择某些侧面即可得到不同的最终朝向,因此断言错误。

第 31 题(单选题,3 分)

将 `anchorX,anchorY,anchorZ` 依次更换为哪项时,对全部合法数据输出不变?

A.
`Left, Front, Down`
B.
`Left, Up, Front`
C.
`Left, Down, Back`
D.
`Down, Right, Front`

正确答案D

解析详情
答案 D朝向编码
思路与推导
  1. D 的 `Down, Right, Front` 仍给出了与原锚点一致的一组合法互相垂直朝向,只是换用了等价编码,因此所有底面权值转移不变。

第 32 题(单选题,2 分)

下列输入的输出为( )。

5 5
2 8 15 1 10
5 19 19 3 5
6 6 2 8 2
12 16 3 8 17
12 5 3 14 13
1 1 1 1 1 1
A.
95
B.
97
C.
94
D.
103

正确答案B

解析详情
答案 B网格动态规划模拟
思路与推导
  1. 按向右和向下滚动后的底面权值更新 36 种朝向状态,到达右下角的最大值为 97,故选 B。

第 33 题(单选题,2 分)

下列输入的输出为( )。

2 5
2 8 15 3 10
5 19 19 3 5
1 2 3 4 5 6
A.
194
B.
157
C.
193
D.
201

正确答案A

解析详情
答案 A网格动态规划模拟
思路与推导
  1. 对 2×52×5 网格逐列进行向右滚动转移,结合权值 `1 2 3 4 5 6`,终点最大加权和为 194。

三、完善程序(1)支付问题

有 nn 种各一张、面值为 aia_i 的纸币,求能支付多少种非零金额。n≤200n\le200,面值总和不超过 5000。

#include <iostream>
using namespace std;
const int MAXN = 210, MAXM = 5010;
int n, m, f[MAXM], a[MAXN];
int main() {
    cin >> n;
    for (int i = 1; i <= n; i++) { cin >> a[i]; ①; }
    ②;
    for (int i = 1; i <= n; i++)
        ③
            f[j] = ④;
    int ans = 0;
    for (int i = 1; i <= m; i++) if (⑤) ans++;
    cout << ans;
    return 0;
}

第 34 题(单选题,3 分)

① 处应填( )。

A.
n += a[i]
B.
m += a[i]
C.
n = a[i]
D.
m = a[i]

正确答案B

解析详情
答案 B子集和上界
思路与推导
  1. `m` 用来记录所有纸币面值之和,后续枚举金额范围为 1~`m`,所以应执行 `m += a[i]`。

第 35 题(单选题,3 分)

② 处应填( )。

A.
f[0] = 1
B.
f[1] = 1
C.
a[0] = 1
D.
a[1] = 1

正确答案A

解析详情
答案 A子集和初始化
思路与推导
  1. 金额 0 在不选择任何纸币时可达,是 0/1 背包的初始状态,因此设 `f[0]=1`。

第 36 题(单选题,3 分)

③ 处应填( )。

A.
for (int j = a[i]; j <= n; j++)
B.
for (int j = n; j >= a[i]; j--)
C.
for (int j = a[i]; j <= m; j++)
D.
for (int j = m; j >= a[i]; j--)

正确答案D

解析详情
答案 D0/1 背包遍历
思路与推导
  1. 每张纸币只能使用一次,金额必须从总和 `m` 递减到 `a[i]`,即选 D。

第 37 题(单选题,3 分)

④ 处应填( )。

A.
f[j - 1] + 1
B.
f[j - a[i]] + 1
C.
f[j] || f[j - a[i]]
D.
f[j] && f[j - a[i]]

正确答案C

解析详情
答案 C可达状态转移
思路与推导
  1. 金额 `j` 原本可达,或金额 `j-a[i]` 可达并加入当前纸币,都能使 `j` 可达,因此为 `f[j] || f[j-a[i]]`。

第 38 题(单选题,3 分)

⑤ 处应填( )。

A.
f[i]
B.
f[i - 1]
C.
f[i] == f[i + 1]
D.
f[i] == f[i - 1]

正确答案A

解析详情
答案 A可达金额计数
思路与推导
  1. 处理完全部纸币后,`f[i]` 为真表示金额 `i` 可支付,遍历 1~`m` 直接统计 `f[i]`。

三、完善程序(2)凑出 17

给 n(1≤n≤20)n(1\le n\le20) 个互不相同的正整数 ai(1≤ai≤109)a_i(1\le a_i\le10^9),在每个数前放 `+` 或 `-`,判断是否能使算式值为 17。

#include <cstdio>
using namespace std;
const int maxn = 25, aim = 17;
int n, a[maxn];
bool ans;
int getBit(const int s, int p) { return ①; }
int main() {
    scanf("%d", &n);
    for (②) scanf("%d", a + i);
    for (int s=0, upperBound=③; s<=upperBound; ++s) {
        ④;
        for (int j=0; j<n; ++j) if (getBit(s,j)==1) sum += a[j];
        else { ⑤; }
        if (int(sum)==aim) { ans=true; break; }
    }
    printf("%s\n", ans ? "Yes" : "No");
}

第 39 题(单选题,3 分)

① 处应填( )。

A.
(s >> p) & 1
B.
(s << p) & 1
C.
s & (1 << p) & 1
D.
s & (1 >> p) & 1

正确答案A

解析详情
答案 A位提取
思路与推导
  1. 右移 `p` 位后与 1,恰好取得整数 `s` 的第 `p` 位,结果为 0 或 1。

第 40 题(单选题,3 分)

② 处应填( )。

A.
int i = 0; i <= n; ++i
B.
int i = 1; i <= n; ++i
C.
int i = 0; i < n; ++i
D.
int i = 1; i < n; ++i

正确答案C

解析详情
答案 C数组下标
思路与推导
  1. 数组按 0~`n-1` 存放 nn 个输入,应使用 `int i=0; i<n; ++i`。

第 41 题(单选题,3 分)

③ 处应填( )。

A.
1 << n
B.
(1 << n) | 1
C.
(1 << n) + 1
D.
(1 << n) - 1

正确答案D

解析详情
答案 D状态枚举
思路与推导
  1. nn 个数的正负号共有 2n2^n 种组合,状态编号为 0~2n−12^n-1,上界应为 `(1<<n)-1`。

第 42 题(单选题,3 分)

④ 处应填( )。

A.
int sum = 0
B.
unsigned long long sum = 0
C.
unsigned short sum = 0
D.
unsigned int sum = 0

正确答案B

解析详情
答案 B整数范围
思路与推导
  1. 最多 20 个不超过 10910^9 的数求和,绝对值可能达到 2×10102×10^{10};给出的类型中只有 `unsigned long long` 能覆盖所需范围。

第 43 题(单选题,3 分)

⑤ 处应填( )。

A.
sum = a[j] + sum
B.
sum = a[j] - sum
C.
sum = -a[j] + sum
D.
sum = -a[j] - sum

正确答案C

解析详情
答案 C正负号枚举
思路与推导
  1. 当前位为 0 时应给 `a[j]` 加负号,即执行 `sum=-a[j]+sum`,与位为 1 时的加法对应。