说明:本卷为模拟练习,题目风格、难度与考点分布参照 CSP-S 提高级初赛(笔试)命制。多项选择题每小题 2 分,全部选对得 2 分,选对但不全得 1 分,有错选得 0 分。本页为题目卷,详细解析见文末(打印时自动隐藏解析)。
一、单项选择题(共 15 题,每题 2 分,共 30 分)
1.十进制整数 2024 对应的十六进制表示是( )。
2.对 n 个元素进行冒泡排序,在最坏情况下的时间复杂度是( )。
A. O(n)
B. O(n log n)
C. O(n²)
D. O(n³)
3.栈(Stack)这种数据结构的访问特性是( )。
A. 先进先出(FIFO)
B. 后进先出(LIFO)
C. 只能访问中间元素
D. 随机访问
4.已知一棵完全二叉树共有 1000 个节点,则其叶子节点的个数为( )。
A. 499
B. 500
C. 501
D. 无法确定
5.快速排序在最坏情况下的时间复杂度为( )。
A. O(n)
B. O(n log n)
C. O(n²)
D. O(n³)
6.对于正整数 x,表达式 x & (x - 1) 的作用是( )。
A. 将 x 变为 0
B. 清除 x 二进制表示中最低位的 1
C. 取出 x 最低位的 1
D. 判断 x 的奇偶性
7.中央处理器(CPU)主要由( )组成。
A. 运算器和控制器
B. 内存和控制器
C. 运算器和内存
D. 控制器和硬盘
8.二分查找(折半查找)算法要求被查找的线性表必须( )。
A. 采用链式存储
B. 元素按关键字有序
C. 元素个数固定
D. 元素互不相同
9.一个无向连通图有 n 个顶点,要保持连通,其最少需要的边数是( )。
10.在 C++ 中,使用 int* p = new int[10]; 动态分配了一个含 10 个 int 的数组,释放该数组的正确方式是( )。
A. delete p;
B. delete[] p;
C. free(p);
D. 不需要释放
11.10 支球队进行单循环赛(每两支球队之间比赛一场),共需要进行( )场比赛。
12.设命题 P 为真、Q 为假,则复合命题 "P 且 Q"(P ∧ Q)的真值为( )。
13.下列方法中,( )不属于解决哈希(散列)冲突的常用方法。
A. 链地址法
B. 开放定址法
C. 二分查找
D. 再哈希法
14.设有递归函数 int gcd(int a,int b){ return b==0 ? a : gcd(b, a%b); },调用 gcd(24, 18) 共产生( )次 gcd 函数调用(含首次调用)。
15.冯·诺依曼体系结构的核心思想是( )。
A. 采用二进制进行运算
B. 存储程序控制(程序与数据一同存储)
C. 引入流水线技术
D. 多核并行处理
三、程序阅读题(共 3 题,每空/每问按标注分值,共约 40 分)
1.(13 分)阅读程序,回答问题。
#include <iostream>
using namespace std;
int f(int n) {
if (n <= 1) return 1;
return f(n - 1) + f(n - 2);
}
int main() {
int a = 0;
for (int i = 1; i <= 5; i++) a += f(i);
cout << a << endl;
return 0;
}
(1)程序运行时输出的结果是______。(4 分)
(2)函数 f(n) 计算的是斐波那契数列的第 n 项(f(1)=f(2)=1),请写出 f(6) 的值______。(4 分)
(3)该程序的 time complexity(时间复杂度)约为______。(5 分)
2.(13 分)阅读程序,回答问题。
#include <iostream>
using namespace std;
int main() {
int a[] = {5, 2, 8, 1, 9, 3};
int n = 6, cnt = 0;
for (int i = 0; i < n; i++)
for (int j = i + 1; j < n; j++)
if (a[i] > a[j]) cnt++;
cout << cnt << endl;
return 0;
}
(1)程序输出结果是______。(4 分)
(2)该程序实际统计的是数组中的______(填"逆序对"或"顺序对")个数。(4 分)
(3)若数组已按从小到大排好序,该程序输出______。(5 分)
3.(14 分)阅读程序,回答问题。
#include <iostream>
using namespace std;
int countBits(int x) {
int c = 0;
while (x) { x &= (x - 1); c++; }
return c;
}
int main() {
int n = 15, ans = 0;
for (int i = 1; i <= n; i++) ans += countBits(i);
cout << ans << endl;
return 0;
}
(1)函数 countBits(x) 的功能是______。(5 分)
(2)当 n = 15 时,程序输出结果是______。(5 分)
(3)该函数 countBits(x) 的时间复杂度与 x 的什么有关?请简要说明。(4 分)
答案解析
【单选 1】A。 2024 = 7×256 + 14×16 + 8 = 1792+224+8,故十六进制为 7E8(E=14)。也可连除 16:2024÷16=126 余 8,126÷16=7 余 14(E),7÷16=0 余 7,从下往上读得 7E8。
【单选 2】C。 冒泡排序每趟将最大元素"冒泡"到末尾,最坏(逆序)需 n-1 趟,总比较次数 n(n-1)/2,时间复杂度 O(n²)。
【单选 3】B。 栈是后进先出(LIFO)结构,只允许在一端(栈顶)进行插入(入栈 push)和删除(出栈 pop)。队列才是先进先出。
【单选 4】B。 完全二叉树叶子节点数为 ⌈n/2⌉。n=1000 为偶数,叶子数 = n/2 = 500。也可推导:前 9 层满共 511 节点,第 10 层 489 个均为叶子;第 9 层 256 个中有 ⌈489/2⌉=245 个有子节点,余 11 个也为叶子;489+11=500。
【单选 5】C。 快速排序最坏情况(如数组已有序且总取首元素作基准)退化为每次只分出 1 个元素,递归深度 n,时间复杂度 O(n²)。平均 O(n log n)。
【单选 6】B。 x & (x-1) 会把 x 二进制最低位的那个 1 变为 0,其余不变。常用于:统计 1 的个数、判断 x 是否为 2 的幂(x & (x-1)==0 即 2 的幂)。
【单选 7】A。 CPU 由运算器(ALU,算术逻辑运算)和控制器(取指、译码、时序控制)组成,辅以寄存器等。
【单选 8】B。 二分查找要求元素"按关键字单调有序",否则无法每次舍弃一半区间。通常采用顺序存储(数组)以便 O(1) 随机访问,但本质前提是有序。
【单选 9】B。 n 个顶点的无向连通图最少边数为 n-1(即一棵树);边再多则可能含环,但保持连通的最小边数固定为 n-1。
【单选 10】B。 用 new[] 分配的数组必须用 delete[] 释放(匹配数组版本),否则行为未定义、可能内存泄漏或崩溃。delete p(非数组版)、free(C 风格,不调析构)均不正确。
【单选 11】A。 单循环赛每两队赛一场,即从 10 队中任取 2 队组合:C(10,2) = 10×9/2 = 45 场。
【单选 12】B。 逻辑"与"(∧)只有参与双方都为真时结果才为真;Q 为假,故 P∧Q 为假。
【单选 13】C。 哈希冲突常用解决方法:开放定址法、链地址法(拉链法)、再哈希法、建立公共溢出区。二分查找是查找算法,与哈希冲突无关。
【单选 14】B。 调用链:gcd(24,18)→gcd(18,6)→gcd(6,0)。共 3 次调用(含首次);到达 gcd(6,0) 直接 return 不再递归。
【单选 15】B。 冯·诺依曼体系核心思想是"存储程序控制"——指令和数据以二进制形式同等存放在存储器中,计算机自动按程序执行。A 是特征之一但非核心思想。
【多选 1】ACD。 稳定排序(相等元素相对次序不变):冒泡、插入、归并、基数。不稳定:快速、选择、堆、希尔排序。
【多选 2】ABC。 平均 O(n log n):堆排序、归并排序、快速排序(平均)。冒泡排序平均/最坏均为 O(n²)。
【多选 3】AB。 图的遍历两大基本方法:深度优先搜索(DFS,栈/递归)与广度优先搜索(BFS,队列)。冒泡、二分与图遍历无关。
【多选 4】ABCD。 数据的逻辑结构分为:集合、线性、树形、图状(网状)四大类。
【多选 5】ABC。 分治思想:将问题分解为子问题、分别求解、合并结果。归并排序、快速排序、二分查找均为典型分治;BFS 基于队列逐层扩展,属"广度优先/分枝限界",一般不归为分治。
【阅读 1】 f 即斐波那契(f(1)=f(2)=1):f(1)=1, f(2)=2, f(3)=3, f(4)=5, f(5)=8, f(6)=13。(1)a = f(1)+…+f(5) = 1+2+3+5+8 = 19。(2)f(6) = 13。(3)朴素递归斐波那契含大量重复计算,调用次数约与 2ⁿ 成正比,时间复杂度 O(2ⁿ)(指数级);可用记忆化/迭代优化到 O(n)。
【阅读 2】 双重循环统计满足 i<j 且 a[i]>a[j] 的 pair 数,即逆序对个数。(1)逐对计数:对 (5,2)(5,1)(5,3)=3,(2,1)=1,(8,1)(8,3)=2,(9,3)=1,合计 7。(2)逆序对。(3)数组若已升序,则不存在 a[i]>a[j](i<j),输出 0。
【阅读 3】 countBits 用 x &= (x-1) 反复清除最低位 1 并计数,故功能是统计整数二进制表示中 1 的个数。(1)功能如上。(2)1~15 各数二进制 1 的个数之和:1+1+2+1+2+2+3+1+2+2+3+2+3+3+4 = 32。(3)时间复杂度与 x 中"1 的个数"成正比(循环每次消一个 1),与 x 的数值大小/位数无关,最坏 O(log x)。
【完善 1】二分查找。 ① 当 a[mid] < key,目标在右半,令 l = mid + 1;② 当 a[mid] > key,目标在左半,令 r = mid - 1。注意用 mid+1/mid-1 避免死循环。
【完善 2】快速排序(挖坑法)。 ③ 从右向左找小于 pivot 的元素,未找到则 j--;④ 从左向右找大于 pivot 的元素,未找到则 i++;⑤ 左半递归 quickSort(a, l, i-1);⑥ 右半递归 quickSort(a, i+1, r)。基准 pivot 已就位在 a[i]。