下⾯关于C++类和对象的说法,错误的是( )。
D:struct 的成员默认访问权限是 public,class 才是 private;A、B 是虚函数规则(析构可为虚、构造不可为虚),C 正确,只有 D 说反了。
对于⼀个具有 个顶点的⽆向图,若采⽤邻接矩阵表⽰,则该矩阵的⼤⼩为( )。
B:n×n。邻接矩阵行、列各对应一个顶点,共 n² 个元素;无向图的矩阵虽沿对角线对称,存储时仍按完整的 n×n 分配。
设有编号为 的 个球和编号为 的 个盒⼦。现将这 个球投⼊ 个盒⼦,要求每个盒⼦放⼀个球,并且恰好有两个球的编号与盒⼦编号相同,问有多少种不同的⽅法?( )。
C:20。先选 2 个球放入编号相同的盒子,C(5,2)=10 种;剩余 3 球放入剩余 3 盒且都不能与盒编号相同,即错排 D(3)=2 种;共 10×2=20。(官方答案 C,库内 answer 字段误记为 D)
从甲地到⼄地,可以乘⾼铁,也可以乘汽车,还可以乘轮船。⼀天中,⾼铁有 班,汽车有 班,轮船有 班。那么⼀天中乘坐这些交通⼯具从甲地到⼄地共有多少种不同的⾛法?( )。
D:17。高铁、汽车、轮船三种走法互斥,任选一班次即一种走法,用分类加法计数原理直接相加:10+5+2=17;若分多段才用乘法。
个结点的⼆叉树,执⾏释放全部结点操作的时间复杂度是( )。
A:O(n)。用后序遍历(DFS 回溯阶段)逐个释放每个结点,n 个结点各 delete 一次,总时间与结点数成正比,与树形无关。
在⼀个单位圆上,随机分布 个点,求这 个点能被⼀个单位半圆周全部覆盖的概率( )。
A:n/2ⁿ⁻¹。经典结论:n 个随机点能落进同一个半圆的概率为 n/2ⁿ⁻¹。验证:n=2 时任意两点必在半圆内,概率 1,只有 A 满足;严格证法是对每个点做对称点后计数。
下⾯ pailie 函数是⼀个实现排列的程序,横线处可以填⼊的是( )。
01#include <iostream> 02using namespace std; 03int sum = 0; 04void swap(int & a, int & b) { 05 int temp = a; 06 a = b; 07 b = temp; 08} 09void pailie(int begin, int end, int a[]) { 10 if (begin == end) { 11 for (int i = 0; i < end; i++) 12 cout << a[i]; 13 cout << endl; 14 } 15 for (int i = begin; i < end; i++) { 16 ___________ // 在此处填入选项 17 } 18}
C:swap(a[begin],a[i]) 把 a[i] 固定到 begin 位,递归排列 begin+1 之后,再换回来恢复现场;A 用 begin+1 越界且撤销不对称,B 递归参数不前进会死循环,D 写法错误。
已知 pailie 函数是实现排列的程序(代码如下),主函数为如下的程序,则最后的排列数是多少个?( )。
01#include <iostream> 02using namespace std; 03int sum = 0; 04void swap(int & a, int & b) { 05 int temp = a; 06 a = b; 07 b = temp; 08} 09void pailie(int begin, int end, int a[]) { 10 if (begin == end) { 11 for (int i = 0; i < end; i++) 12 cout << a[i]; 13 cout << endl; 14 } 15 for (int i = begin; i < end; i++) { 16 swap(a[begin], a[i]); 17 pailie(begin + 1, end, a); 18 swap(a[i], a[begin]); 19 } 20}
主函数如下:
01int main() { 02 int a[5] = {1, 2, 3, 4, 5}; 03 pailie(0, 5, a); 04 return 0; 05}
A:120。pailie(0,5) 对 5 个互不相同的元素 {1,2,3,4,5} 做全排列,输出 5!=120 行,即排列数 120。
下列程序实现了输出杨辉三角形,代码中横线部分应该填⼊的是( )。
01#include <iostream> 02using namespace std; 03#define N 35 04int a[N][N]; 05int main() { 06 int n; 07 cin >> n; 08 for (int i = 1; i <= n; i++) 09 for (int j = 1; j <= i; j++) { 10 if (j == 1 || j == i) 11 a[i][j] = 1; 12 else 13 __________ // 在此处填入选项 14 } 15 for (int i = 1; i <= n; i++) { 16 for (int j = 1; j <= i; j++) 17 cout << a[i][j]; 18 cout<<endl; 19 } 20 return 0; 21}
A:杨辉三角递推 C(i-1,j-1)+C(i-1,j)=C(i,j),即上一行相邻两数之和;B、C、D 的索引组合取不到上一行的左右两数,结果必错。
下⾯最⼩⽣成树的 算法程序中,横线处应该填⼊的是( )。
01#include <iostream> 02#include <vector> 03#include <algorithm> 04using namespace std; 05struct Edge { 06 int u, v, weight; 07 bool operator <(const Edge & other) const { 08 return weight < other.weight; 09 } 10}; 11int findParent(int vertex, vector<int> & parent) { 12 if (parent[vertex] == -1) 13 return vertex; 14 return parent[vertex] = findParent(parent[vertex], parent); 15} 16int main() { 17 int n, m; 18 cin >> n >> m; // n: 顶点数,m: 边数 19 vector<Edge> edges(m); 20 vector<int> parent(n, -1); 21 int totalWeight = 0; 22 for (int i = 0; i < m; i++) 23 cin >> edges[i].u >> edges[i].v >> edges[i].weight; 24 sort(edges.begin(), edges.end()); 25 26 for (const auto & edge : edges) { 27 int uParent = findParent(edge.u, parent); 28 int vParent = findParent(edge.v, parent); 29 if (________) { // 在此处填入选项 30 parent[uParent] = vParent; 31 totalWeight += edge.weight; 32 } 33 } 34}
C:uParent != vParent。Kruskal 按边权升序加边,仅当两端点不在同一连通分量(并查集根不同)时才合并该边并累加权重;根相同说明成环应跳过。
下⾯ 算法程序中,横线处应该填⼊的是( )。
01#include <iostream> 02#include <vector> 03#include <algorithm> 04using namespace std; 05int prim(vector<vector<int>> & graph, int n) { 06 vector<int> key(n, INT_MAX); 07 vector<int> parent(n, -1); 08 key[0] = 0; 09 for (int i = 0; i < n; i++) { 10 int u = min_element(key.begin(), key.end()) - key.begin(); 11 if (key[u] == INT_MAX) 12 break; 13 for (int v = 0; v < n; v++) { 14 if (_____________________ ) { // 在此处填入选项 15 key[v] = graph[u][v]; 16 parent[v] = u; 17 } 18 } 19 } 20 int sum = 0; 21 for (int i = 0; i < n; i++) { 22 if (parent[i] != -1) { 23 cout << "Edge: " << parent[i] << " - " << i << " Weight: " << key[i] << endl; 24 sum += key[i]; 25 } 26 } 27 return sum; 28} 29int main() { 30 int n, m; 31 cin >> n >> m; 32 vector<vector<int>> graph(n, vector<int>(n, 0)); 33 for (int i = 0; i < m; i++) { 34 int u, v, w; 35 cin >> u >> v >> w; 36 graph[u][v] = w; 37 graph[v][u] = w; 38 } 39 int result = prim(graph, n); 40 cout << "Total weight of the minimum spanning tree: " << result << endl; 41 return 0; 42}
D:graph[u][v]!=0 && key[v]>graph[u][v]。邻接矩阵中 0 表示无边,!=0 保证存在边;key[v]>graph[u][v] 表示经 u 到 v 的边更短才更新;A 会把无边当边,B、C 与权值含义矛盾。
下列 算法中,横线处应该填⼊的是( )。
01#include <iostream> 02using namespace std; 03 04#define N 100 05int n, e, s; 06const int inf = 0x7ffffff; 07int dis[N + 1]; 08int cheak[N + 1]; 09int graph[N + 1][N + 1]; 10int main() { 11 for (int i = 1; i <= N; i++) 12 dis[i] = inf; 13 cin >> n >> e; 14 for (int i = 1; i <= e; i++) { 15 int a, b, c; 16 cin >> a >> b >> c; 17 graph[a][b] = c; 18 } 19 cin >> s; 20 dis[s] = 0; 21 for (int i = 1; i <= n; i++) { 22 int minn = inf, minx; 23 for (int j = 1; j <= n; j++) { 24 if (_______) { // 在此处填入选项 25 minn = dis[j]; 26 minx = j; 27 } 28 } 29 cheak[minx] = 1; 30 for (int j = 1; j <= n; j++) { 31 if (graph[minx][j] > 0) { 32 if (minn + graph[minx][j] < dis[j]) { 33 dis[j] = minn + graph[minx][j]; 34 } 35 } 36 } 37 } 38}
B:dis[j]<minn && cheak[j]==0。每轮在未确定最短路(cheak=0)的顶点中选当前 dis 最小者;A、C 比较方向错会选出更大或相等的,D 选了已确定顶点,均破坏贪心。
下⾯ 算法中,横线处应该填⼊的是( )。
01#include <iostream> 02using namespace std; 03 04#define N 21 05#define INF 99999999 06int map[N][N]; 07int main() { 08 int n, m, t1, t2, t3; 09 cin >> n >> m; 10 for (int i = 1; i <= n; i++) { 11 for (int j = 1; j <= n; j++) { 12 if (i == j) 13 map[i][j] = 0; 14 else 15 map[i][j] = INF; 16 } 17 } 18 for (int i = 1; i <= m; i++) { 19 cin >> t1 >> t2 >> t3; 20 map[t1][t2] = t3; 21 } 22 for (int k = 1; k <= n; k++) 23 for (int i = 1; i <= n; i++) 24 for (int j = 1; j <= n; j++) 25 if (_______) // 在此处填入选项 26 map[i][j] = map[i][k] + map[k][j]; 27 for (int i = 1; i <= n; i++) { 28 for (int j = 1; j <= n; j++) { 29 cout.width(4); 30 cout << map[i][j]; 31 } 32 cout << endl; 33 } 34}
B:map[i][j]>map[i][k]+map[k][j]。Floyd 以 k 为中转点松弛,仅当经 k 的路径更短时更新;A 方向相反会写入更长路径,C、D 用减法无意义。
下⾯程序的 Merge_Sort 函数时间复杂度为( )。
01void Merge(int a[], int left, int mid, int right) { 02 int temp[right - left + 1]; 03 int i = left; 04 int j = mid + 1; 05 int k = 0; 06 while (i <= mid && j <= right) { 07 if (a[i] < a[j]) 08 temp[k++] = a[i++]; 09 else 10 temp[k++] = a[j++]; 11 } 12 while (i <= mid) 13 temp[k++] = a[i++]; 14 while (j <= right) 15 temp[k++] = a[j++]; 16 for (int m = left, n = 0; m <= right; m++, n++) 17 a[m] = temp[n]; 18} 19void Merge_Sort(int a[], int left, int right) { 20 if (left == right) 21 return; 22 int mid = (left + right) / 2; 23 Merge_Sort(a, left, mid); 24 Merge_Sort(a, mid + 1, right); 25 Merge(a, left, mid, right); 26}
A:O(n log n)。归并排序每次把区间对半分,递归深度 log n,每层合并总耗时 O(n),故总 O(n log n),与输入顺序无关。
下⾯ 函数的时间复杂度为( )。
01int fibonacci(int n) { 02 if (n <= 1) 03 return n; 04 else 05 return fibonacci(n - 1) + fibonacci(n - 2); 06}
B:无记忆化斐波那契 T(n)=T(n-1)+T(n-2),递归树近似满二叉树,复杂度指数级 O(φⁿ)(φ 为递推特征根,约 1.618,选项以 φ 表之),其余选项阶数都太低。
表达式 '3' & 1 的结果为 '1' 。
B:错误。'3' 的 ASCII 码是 51(二进制 0b110011),与 1 按位与得 0b1 即整数值 1;char 参与运算自动提升为 int,结果是整数 1 而非字符 '1'。
在C++语⾔中,变量定义必须在某⼀个函数定义之内。
B:错误。变量可以定义在函数之外成为全局变量,也可定义在类、命名空间等作用域中,并非必须在某个函数定义之内;函数内定义的只是局部变量。
冒泡排序⼀般是不稳定的。
B:错误。冒泡排序只交换相邻的逆序对,相等元素不会互相越过,是稳定排序;不稳定的是选择、快速、堆、希尔排序,这四类会打乱相等元素次序。
⼆叉排序树的查找操作的平均时间复杂度,正⽐于树的⾼度。
A:正确。BST 查找每步沿一条分支下降一层,比较次数等于从根到目标结点的路径长度,平均正比于树高;平衡时 O(log n),退化链时 O(n)。
使⽤ 或 头⽂件中的余弦函数,表达式 cos(60) 的结果类型为 double 、值约为 。
B:错误。cos 的参数以弧度为单位,cos(60) 是 60 弧度的余弦约为 0.154;0.5 对应 cos(π/3),即 60 度须先转成弧度。
你有三种硬币,分别⾯值 元、 元和 元,每种硬币都有⾜够多。买⼀本书需要 元,则最少可以⽤ 个硬币组合起来正好付清,且不需要对⽅找钱。
A:正确。27=7+5+5+5+5,1 个 7 元加 4 个 5 元共 5 枚;4 枚以内逐一试 7、5、2 的组合凑不出 27(如 7×3+2×3 需 6 枚),故 5 枚最少。
现有 个完全相同的元素,要将其分为 组,允许每组可以有 个元素,则⼀共有 种分组⽅案。
B:错误。允许空组的隔板法是 C(n+k-1,k-1)(n 个球与 k-1 块板混排,板可相邻);C(n-1,k-1) 是每组至少 1 个的非空分组答案。
已知 int 类型的变量 和 中分别存储着⼀个直角三角形的两条直角边的长度,则该三角形的⾯积可以通过表达式 a / 2.0 * b 求得。
A:正确。a/2.0 先把 int 隐式转成 double 再除,无整数截断,结果 0.5a 再乘 b 即精确面积;若写成 a/2*b 才会因整数除法出错。
已知等差数列的通项公式 ,则前 项和的求和公式为 。使⽤这⼀公式计算 的时间复杂度是 。
A:正确。等差求和公式 Sₙ=n(a₁+aₙ)/2 一步算出,只做常数次加减乘除,与 n 的规模无关,时间复杂度 O(1)。
诚实国公民只说实话,说谎国公民只说谎话。你来到⼀处分岔⼝,⼀条通往诚实国,⼀条通往说谎国,但不知是哪⼀条通往哪⾥。正在为难之际,⾛来两位路⼈,他们都⾃称是诚实国公民,都说对⽅是说谎国公民。你想去说谎国,可以这样问其中⼀位路⼈:“我要去说谎国,如果我去问另⼀个路⼈,他会指向哪⼀条路?”。
A:正确。两路人一真一假。问 A『问 B 他会指哪条路』:A 诚实则如实转述 B 的假话,A 说谎则把 B 的真话反着说,两者都指向诚实国方向,取反即说谎国之路。