说明:本卷为模拟练习(卷三),聚焦补码/组合/图论/位运算/数论 GCD-LCM/排序稳定性进阶等考点。多项选择题每小题 2 分,全部选对得 2 分,选对但不全得 1 分,有错选得 0 分。打印时自动隐藏解析。
一、单项选择题(共 15 题,每题 2 分,共 30 分)
1.在 8 位带符号整数(采用补码表示)中,能表示的整数范围是( )。
A. -127 ~ 127
B. -128 ~ 127
C. 0 ~ 255
D. -128 ~ 128
2.从 5 个不同元素中任取 3 个排成一列(排列数 P(5,3))为( )。
3.无向完全图 K₆(6 个顶点两两相连)的边数为( )。
4.哈希函数 h(key) = key % 11,则 key = 38 的哈希地址(桶下标)是( )。
5.对任意整数 x,位运算表达式 x ^ x(按位异或)的结果是( )。
6.一棵二叉树共有 10 个节点,则其分支(边)的总数为( )。
7.用朴素递归实现斐波那契数列(f(n)=f(n-1)+f(n-2)),其递归调用所占的空间复杂度约为( )。
A. O(1)
B. O(n)
C. O(n²)
D. O(log n)
8.下列排序算法中,不属于"基于比较"的排序的是( )。
A. 堆排序
B. 归并排序
C. 计数排序
D. 快速排序
9.Dijkstra 单源最短路算法要求图中边的权值必须满足( )。
A. 可以为负
B. 必须非负
C. 必须为整数
D. 无要求
10.拓扑排序(Topological Sort)只能应用于( )。
A. 无向图
B. 有向无环图(DAG)
C. 任意有向图
D. 完全图
11.C++ 函数形参写为 void f(int &x),表示 x 是( )。
A. 指针参数
B. 引用参数(修改会影响实参)
C. 常量参数
D. 数组参数
12.命题"若 P 则 Q"的逆否命题是( )。
A. 若 Q 则 P
B. 若非 Q 则非 P
C. 若 P 则非 Q
D. 若非 P 则非 Q
13.栈的入栈序列为 1、2、3、4(依次入栈),则下列出栈序列中不可能出现的是( )。
A. 1, 2, 3, 4
B. 4, 3, 2, 1
C. 3, 1, 2, 4
D. 2, 4, 3, 1
14.下列排序算法中,最坏情况下时间复杂度为 O(n²) 的是( )。
A. 堆排序
B. 归并排序
C. 快速排序
D. 堆排序与归并排序
15.在下列存储器中,CPU 访问速度最慢的是( )。
A. 寄存器
B. Cache(高速缓存)
C. 内存(RAM)
D. 硬盘(外存)
三、程序阅读题(共 3 题,每空/每问按标注分值,共约 40 分)
1.(13 分)阅读程序,回答问题。
#include <iostream>
using namespace std;
int main() {
int n = 5, total = 0;
for (int mask = 0; mask < (1 << n); mask++) {
int bits = 0;
for (int i = 0; i < n; i++)
if (mask & (1 << i)) bits++;
if (bits == 2) total++;
}
cout << total << endl;
return 0;
}
(1)程序输出结果是______。(4 分)
(2)该程序实际统计的是______。(4 分)
(3)若将判断改为 if (bits == n),程序输出结果是______。(5 分)
2.(13 分)阅读程序,回答问题。
#include <iostream>
using namespace std;
int main() {
int n = 6;
int f[10] = {0};
f[1] = 1; f[2] = 2;
for (int i = 3; i <= n; i++) f[i] = f[i - 1] + f[i - 2];
cout << f[n] << endl;
return 0;
}
(1)程序输出结果是______。(4 分)
(2)f(n) 在本程序中表示的实际意义是______。(4 分)
(3)f(n) 与斐波那契数列有何关系?______。(5 分)
3.(14 分)阅读程序,回答问题。
#include <iostream>
using namespace std;
int lcm(int a, int b) {
int x = a, y = b;
while (y) { int t = x % y; x = y; y = t; }
return a * b / x;
}
int main() {
cout << lcm(12, 18) << endl;
return 0;
}
(1)程序输出结果是______。(4 分)
(2)函数中被 while 循环求出的 x 最终值代表什么?该算法名称是______。(5 分)
(3)若调用 lcm(0, 5),程序会出现什么问题?______。(5 分)
答案解析
【单选 1】B。 8 位补码:符号位占 1 位,数值 7 位,范围为 -2⁷ ~ 2⁷-1 = -128 ~ 127(注意 -128 用 10000000 表示,无对应正数 +128)。
【单选 2】C。 排列数 P(5,3)=5×4×3=60;组合数 C(5,3)=10。区分"排列(有序)"与"组合(无序)"。
【单选 3】B。 无向完全图边数 = C(6,2)=6×5/2=15。
【单选 4】C。 38 % 11 = 5(11×3=33,余 5),故哈希地址为 5。
【单选 5】B。 异或(^)规则:相同为 0、不同为 1;任何数异或自身得 0,即 x^x=0。常用于"不借助临时变量交换两数""找只出现一次的数"。
【单选 6】A。 任何树(含二叉树)的边数 = 节点数 - 1 = 10 - 1 = 9。
【单选 7】B。 朴素递归斐波那契每次调用产生两个子调用,递归树深度为 n,调用栈深度 O(n),故空间复杂度 O(n)(时间才是 O(2ⁿ))。
【单选 8】C。 计数排序、桶排序、基数排序属于"非比较排序"(基于键值分布),可突破 O(n log n) 下界;堆/归并/快排是基于比较的排序。
【单选 9】B。 Dijkstra 算法要求边权非负;若存在负权边需用 Bellman-Ford 等算法。
【单选 10】B。 拓扑排序只能用于有向无环图(DAG),常用于任务依赖排序;有环则无拓扑序。
【单选 11】B。 int &x 是引用参数,函数内对 x 的修改会直接影响实参(别名);指针写法是 int *x。
【单选 12】B。 "若 P 则 Q" 的逆否命题为 "若非 Q 则非 P",二者真值等价;A 是逆命题,D 是否命题。
【单选 13】C。 出栈序列 3,1,2,4:要第一个出 3,须 1、2、3 依次入栈(栈底1、中2、顶3),出 3 后栈顶是 2,下一个只能出 2 而不能出 1,故 3,1,2 不可能。其余均可构造。
【单选 14】C。 堆排序、归并排序最坏均为 O(n log n);快速排序最坏(如有序且取首/尾基准)退化为 O(n²)。
【单选 15】D。 存储速度由快到慢:寄存器 > Cache > 内存(RAM) > 外存(硬盘)。硬盘最慢。
【多选 1】AB。 Prim 与 Kruskal 均求最小生成树;Dijkstra 是最短路、Floyd 是全源最短路。
【多选 2】AB。 树、图是典型非线性结构;队列、栈是线性结构。
【多选 3】ABD。 堆排序(O(1))、快速排序(递归栈 O(log n))、冒泡排序(O(1))均为原地排序;归并排序需 O(n) 额外数组,非原地。
【多选 4】ABCD。 栈实现函数调用栈;队列实现 BFS;哈希表平均 O(1) 查找;二分查找前提是有序。全对。
【多选 5】ABC。 时间复杂度描述增长趋势(A 对);O(n²)>O(n log n)(B 对);空间复杂度可为 O(1)(C 对);递归不一定 O(n) 空间——尾递归或迭代可 O(1)(D 错)。
【阅读 1】 程序枚举 0~2⁵-1 的所有掩码,统计其中"恰好有 2 个二进制位为 1"的个数。(1)即 C(5,2)=10,输出 10。(2)实际统计的是从 5 个元素中选取 2 个的组合数(子集枚举思想)。(3)bits==n 即"5 位全为 1",只有 mask=31 一个,输出 1。
【阅读 2】 f 为爬楼梯递推:f(1)=1, f(2)=2, f(3)=3, f(4)=5, f(5)=8, f(6)=13。(1)输出 13。(2)f(n) 表示走 n 级台阶、每次可上 1 或 2 阶的走法总数。(3)f(n)=Fib(n+1),即斐波那契数列第 n+1 项(Fib(1)=1,Fib(2)=1,Fib(3)=2… 此处 f(6)=13=Fib(7))。
【阅读 3】 while 循环用辗转相除法求 a、b 的最大公约数,循环结束时 x 即 gcd。(1)gcd(12,18)=6,lcm=12×18/6=36。(2)x 最终值为最大公约数(gcd),算法名为欧几里得算法(辗转相除法)。(3)若 a=0,循环中 y=b=5,x=0,t=x%y=0%5=0,x=5,y=0 退出,x=5(gcd(0,5)=5),然后 a*b/x = 0*5/5 = 0,不会除零——但若 b=0、a=0,则 x=0 后 a*b/x = 0/0 产生除零错误/未定义行为;另外若其中一者为 0 而另一非 0 时结果为 0(lcm(0,5)=0 数学上 lcm(0,k)=0 也成立)。本题点:需防范两参数同时为 0 的除零。
【完善 1】辗转相除法。 ① 求余数 t = a % b;② a = b;③ b = t;④ 循环结束 b=0,此时 a(即原 x 保留的 gcd)为结果,return a。
【完善 2】冒泡排序。 ① 每趟把当前最大元素"冒泡"到末尾,第 i 趟只需比较到 n-1-i,故 j < n-1-i;② 相邻逆序则交换,条件 a[j] > a[j+1]。