2023年12月真题
一、单选题(每题2分,共30分)
正确答案:D
考察知识点:类和对象
解析:自定义函数中不能嵌套定义新函数。
正确答案:C
考察知识点:类和对象
解析:内部类是需要通过外部类访问的。
正确答案:C
考察知识点:类和对象
解析:objCounter 是静态成员,2 种方式都可以访问。
正确答案:D
考察知识点:类和对象
解析:析构函数可以省略。系统可以默认一个析构函数。
正确答案:B
考察知识点:类和对象、二叉树
解析:对二叉树的先序遍历,根左右。
正确答案:B
考察知识点:链表
解析:实现一个链表,指向前面和后面的元素。
正确答案:B
考察知识点:霍夫曼编码
解析:霍夫曼编码。。按照出现次数进行赫夫曼编码。
正确答案:D
考察知识点:算法
解析:fiboA 函数会存在重复计算,执行效率不高。
正确答案:B
考察知识点:二叉树
解析:左右孩子也可以作为参数,不一定只有根节点。
正确答案:D
考察知识点:完全二叉树
解析:完全二叉树和满二叉树的节点下标是连续的,其他类型的节点数不确定,下标不一定连续,就不宜用 list 存储。
正确答案:A
考察知识点:二叉树
解析:构造二叉树,用括号表示法。1 是根结点,其左右孩子为2,3,写成1(2)(3)。用同样的思路构建左子树和右子树,选 A。
正确答案:A
考察知识点:函数的定义和调用
解析:bool 类型函数只能返回布尔类型,布尔值只有0 或者1。
正确答案:B
考察知识点:计算机基础知识
解析:本题考察计算机基础知识。通信卫星可以转发无线电信号,实现通信地球站间或地球站与航天器间的无线电通信,因此具有信号中继作用。选B。
正确答案:C
考察知识点:数学知识
解析:本题考察数学知识。线筛和埃筛都可以判断素数,枚举也可以,二分规模减半,不能合理判断。
正确答案:B
考察知识点:排序知识
解析:冒泡排序和快速排序,都属于交换排序。
交换排序:冒泡排序、快速排序
选择排序:简单选择排序、堆排序
插入排序:直接插入排序、希尔排序
二、判断题(每题2分,共20分)
正确答案:正确
考察知识点:类
解析:方法在 c++中也就是类内的函数。
正确答案:正确
考察知识点:类
解析:构造函数没有,系统会给一个默认的构造函数。
正确答案:正确
考察知识点:类
解析:标准库类型 vector 和 string 都重载了下标运算符。
正确答案:正确
考察知识点:算法
解析:深搜就是“能深则深、不能深则退”。
正确答案:错误
考察知识点:哈夫曼编码
解析:哈夫曼编码确实是唯一的。但是,这并不意味着它总是有确定的压缩率。压缩率通常定义为压缩后数据大小与原始数据大小的比值。对于哈夫曼编码来说,压缩率会受到输入数据的特性(如字符频率分布)的影响。不同的输入数据,即使使用相同的哈夫曼编码算法,也可能得到不同的压缩率。
正确答案:错误
考察知识点:指针
解析:一个指针的指向对象已被删除,那么就成了悬空指针。指针本身仍然存在,但它的指向变得不确定,因为原来的内存已经被释放并可能被重新分配给其他用途。可能会导致程序崩溃,但是可能正常执行。
正确答案:正确
考察知识点:二叉搜索树
解析:在理想情况下(即树是平衡的),二叉搜索树的高度为 h = l o g 2 ( N + 1 ) h=log_{2}(N+1) h=log2(N+1),其中 N N N 是节点的数量。对于查找操作,每次比较都能排除树的一半,所以查找的时间复杂度为 O ( l o g N ) O(logN) O(logN)。
然而,在最坏情况下(例如树退化成链表),二叉搜索树的高度为N,此时查找的时间复杂度为 O ( N ) O(N) O(N)。
平均情况下,二叉搜索树查找的时间复杂度确实是 O ( l o g N ) O(logN) O(logN)。
正确答案:正确
考察知识点:二叉搜索树
解析:若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值;若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值;它的左、右子树也分别为二叉排序树。平均情况下是一分为二。
正确答案:正确
考察知识点:算法
解析:可以的。N 除了自身,只能有 1 个大于等于n/2 的因子。
正确答案:正确
考察知识点:算法
解析:都是相邻的数字交换。
三、编程题(每题25分,共50分)
本题考察 动态规划
从 0 关出发,每次都有 m 种选择,选第i 个关卡,到达的下一个关卡是 0 + m i 0+ m_i 0+mi,同时获得第i个关卡的关卡分数。当关卡的总和大于等于 N 的时候,便停止游戏。求通关时最多能够获得的分数。
游戏开始,处在第0关,且通道 1 < = a i < = N 1<=a_i<=N 1<=ai<=N,因此经过的关卡只能越来越大,可以从关卡0遍历上去。给除0之外的关卡设定一个最小值(-2147483648)的初始得分,0关卡的初始得分为0,当遍历到第i个关卡,如果其值不为最小值,说明其可达(从0关卡经过若干步到达),则给从i关卡可到的关卡赋值。如果原值比较大,保持不变,如果从i过去更大,则更新成更大的值。
#include<bits/stdc++.h>
using namespace std;
const int N=1e4;
const int INF=-2147483648;
int n, m, a[100], b[N], dp[N+1];
int main() {
cin>>n>>m;
for(int i=0; i<m; i++) cin>>a[i];
for(int i=0; i<n; i++) cin>>b[i];
//将除0之外关卡的初始得分置为最小值,表示不可达
for(int i=1; i<=n; i++) dp[i]=INF;
for(int i=0; i<n; i++) {
if(dp[i] != INF) {
//如果关卡i可达,计算下一个可达关卡的最多得分
for(int j=0; j<m; j++) {
int pos = i+a[j]>=n ? n : i+a[j]; //通关得分记录在dp[n]
dp[pos] = max(dp[pos], dp[i]+b[i]);
}
}
}
cout<<dp[n];
return 0;
}
本题考察 树结构,深搜
n个员工,编号0~n-1,m个员工参与一个会议,找一个人主持会议,要求这个人可以管理与会的所有人,一个人可以管理自己,管理自己的直接下属,管理自己直接下属的下属,如果多人满足要求,求出最大的编号。本题本质上是求多个点的最近公共祖先(LCA)
数据量不大,且某员工的编号一定小于其直接领导的编号,可以按照编号从大到小进行遍历,判断该编号的员工是否可以领导所有与会者。
#include<bits/stdc++.h>
using namespace std;
int n, f[300], q, m, a[300];
//判断x是否可以管理y
bool find(int x, int y){
if(y==0 && x!=0) return false; //如果y是0但x不是0,则x不可能管理y,返回false
if(f[y] == x) return true; //如果x是y的直系领导,返回true
return find(x, f[y]); //x是否是y的领导的领导
}
//判断x是否可以管理所有与会者
bool check(int x){
for(int i=0; i<m; i++){
//x可以管理第i个与会者:1、x就是第i个与会者;2、x是第i个与会者的直接或者间接领导
//都不符合,则返回false,只要有一个管理不了,即意味着管理不了所有与会者
if(x!=a[i] && !find(x, a[i])) return false;
}
return true;
}
int main() {
cin>>n;
for(int i=1; i<n; i++) cin>>f[i];
cin>>q;
while(q--){
cin>>m;
for(int i=0; i<m; i++) cin>>a[i];
for(int i=n-1; i>=0; i--){
//按编号从大到小遍历所有人,如果某个人可以管理所有与会者,则输出
if(i==0) cout<<0<<endl;
else if(check(i)){
cout<<i<<endl;
break;
}
}
}
return 0;
}