试卷解析 · 理解每一步
2023-12-Level-7
2023-12-Level-7
试卷解析总览,可直接查看每题答案与解析。
第 1 题(单选题,2 分)
定义变量 double x,如果下面代码输入为 100,输出最接近()。
#include <iostream>
#include <string>
#include <cmath>
#include <vector>
using namespace std;
int main()
{
double x;
cin >> x;
cout << log10(x) - log2(x) << endl;
cout << endl;
return 0;
}正确答案B
解析详情
输入的 100 是 x,不是题目个数。程序计算的是 log10(100)-log2(100)=2-6.64...≈-4.64,所以最接近 -5。
第 2 题(单选题,2 分)
对于下面动态规划方法实现的函数,以下选项中最适合表达其状态转移函数的为()。
int s[MAX_N], f[MAX_N][MAX_N];
int stone_merge(int n, int a[]) {
for (int i = 1; i <= n; i++)
s[i] = s[i - 1] + a[i];
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
if (i == j)
f[i][j] = 0;
else
f[i][j] = MAX_F;
for (int l = 1; l < n; l++)
for (int i = 1; i <= n - 1; i++)
int j = i + 1;
for (int k = i; k < j; k++)
f[i][j] = min(f[i][j], f[i][k] + f[k + 1][j] + s[j] - s[i - 1]);
}
return f[1][n];
}正确答案D
解析详情
f[i][j] 表示把区间 [i,j] 合并成一堆的最小代价,枚举断点 k 后有 f[i][j]=min(f[i][k]+f[k+1][j])+sum(i,j)。代码中的 s[j]-s[i-1] 正是区间和,所以 D 与程序一致。
第 3 题(单选题,2 分)
下面代码可以用来求最长上升子序列(LIS)的长度,如果输入是:5 1 7 3 5 9,则输出是()。
int a[2023], f[2023];
int main()
{
int n, i, j, ans = -1;
cin >> n;
for (i = 1; i <= n; i++) {
cin >> a[i];
f[i] = 1;
}
for (i = 1; i <= n; i++) {
for (j = 1; j < i; j++) {
if (a[j] < a[i]) {
f[i] = max(f[i], f[j] + 1);
}
}
}
for (i = 1; i <= n; i++) {
ans = max(ans, f[i]);
cout << f[i] << " ";
}
cout << ans << endl;
return 0;
}正确答案B
解析详情
首个 5 是 n,序列实际为 1,7,3,5,9。对应 f 依次是 1,2,2,3,4,最后 ans=4,所以输出为 1 2 2 3 4 4。
第 4 题(单选题,2 分)
C++ 语言中,下列关于关键字 static 的描述不正确的是()。
正确答案C
解析详情
static 成员函数确实存在,静态常量成员也可以在类外定义;静态存储期对象通常在 main 前初始化、main 结束后析构。C 错在“地址都可以访问”这一句,能否访问还受 public/private 限制。
第 5 题(单选题,2 分)
G 是一个非连通无向图,共有 28 条边,则该图至少有()个顶点。
正确答案D
解析详情
8 个顶点的完全图边数是 8×7÷2=28,但完全图一定连通,不满足“非连通”。要保留 28 条边又非连通,只能让 8 个点构成完全图,再加 1 个孤立点,因此至少 9 个顶点。
第 6 题(单选题,2 分)
哈希表长31,按照下面的程序依次输入 4 17 28 30 4,则最后的 4 存入哪个位置?()
#include <iostream>
#include <string>
#include <cmath>
#include <vector>
using namespace std;
const int N=31;
int htab[N], flag[N];
int main()
{
int n, x, i, j, k;
cin >> n;
for (i=0; i<n; i++) {
cin >> x;
k=x%13;
while (flag[k]) k = (k+1)%13;
htab[k]=x;
flag[k]=1;
}
for (i=0; i<N; i++)
cout << htab[i] << " ";
cout << endl;
return 0;
}正确答案D
解析详情
首个 4 是输入个数 n,真正插入的是 17,28,30,4。它们的位置依次为 17→4,28→2,30 由 4 冲突后到 5,最后 4 从 4 开始线性探测,4、5 已占,存到 6。
第 7 题(单选题,2 分)
某二叉树 T 的先序遍历序列为:,中序遍历序列为:,则下列说法中正确的是()。
正确答案B
解析详情
根结点是 A。由中序可还原出左侧链 B→D→F,右子树为 C,其左子树根为 E,E 的左右孩子分别是 G、H。最长路径长度为 A-B-D-F 或 A-C-E-G,共 4 层,所以 B 正确。
第 8 题(单选题,2 分)
下面代码段可以求两个字符串 s1 和 s2 的最长公共子串(LCS),下列相关描述不正确的是()。
while (cin >> s1 >> s2)
{
memset(dp, 0, sizeof(dp));
int n1 = strlen(s1), n2 = strlen(s2);
for (int i = 1; i <= n1; ++i)
for (int j = 1; j <= n2; ++j)
if (s1[i - 1] == s2[j - 1])
dp[i][j] = dp[i - 1][j - 1] + 1;
else
dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]);
cout << dp[n1][n2] << endl;
}正确答案C
解析详情
这段转移式 dp[i][j]=max(dp[i-1][j],dp[i][j-1]) 实际求的是最长公共子序列,不是子串;其时间和空间复杂度都是 O(n1×n2)。二维 DP 可以压成两行甚至一行,因此“空间复杂度已经最优”不成立。
第 9 题(单选题,2 分)
图的广度优先搜索中既要维护一个标志数组标志已访问的图的特点,还需哪种结构存放结点以实现遍历?()
正确答案B
解析详情
BFS 按“先发现先扩展”的层次顺序访问结点,待访问结点必须按先进先出管理,所以要配合队列使用。
第 10 题(单选题,2 分)
对关键字序列 {44, 36, 23, 35, 52, 73, 90, 58} 建立哈希表,哈希函数为 h(k)=k%7,执行下面的 Insert 函数,则等概率情况下的平均成功查找长度(即查找成功时的关键字比较次数的均值)为( )。
#include <iostream>
#include <string>
#include <cmath>
#include <vector>
using namespace std;
typedef struct Node{
int data;
struct Node *next;
} Node;
Node* hTab[7];
int key[] = {44, 36, 23, 35, 52, 73, 90, 58, 0};
void Insert()
{
int i, j;
Node *x;
for (i = 0; key[i]; i++) {
j = key[i] % 7;
x = new Node;
x->data = key[i];
x->next = hTab[j];
hTab[j] = x;
}
}正确答案C
解析详情
按 key%7 分桶后得到:0 桶 {35},1 桶 {36},2 桶头插后为 {58,23,44},3 桶为 {73,52},6 桶为 {90}。成功查找比较次数分别是 1,1,1,2,3,1,2,1,总和 12,平均 12/8=1.5。
第 11 题(单选题,2 分)
学生在读期间所上的某些课程中需要先上其他的课程,所有课程和课程间的先修关系构成一个有向图 G,有向边 <U,V> 表示课程 U 是课程 V 的先修课,则要找到某门课程 C 的全部先修课下面哪种方法不可行?()
正确答案D
解析详情
要找课程 C 的全部先修课,本质是找所有能到达 C 的顶点;把边反向后做 BFS 或 DFS 都可以。动态规划不直接解决一般有向图的可达性枚举,因此 D 不可行。
第 12 题(单选题,2 分)
一棵完全二叉树有 2023 个结点,则叶结点有多少个?()
正确答案C
解析详情
完全二叉树编号为 1 到 n 时,1 到 ⌊n/2⌋ 都是非叶子,叶子数为 n-⌊n/2⌋=⌈n/2⌉。n=2023 时叶子数为 2023-1011=1012。
第 13 题(单选题,2 分)
用下面的邻接表结构保存一个有向图 G,InfoType 和 VertexType 是定义好的类。设 G 有 n 个顶点、e 条弧,则求图 G 中某个顶点 u (其顶点序号为 k)的度的算法复杂度是()。
typedef struct ArcNode{
int adjvex; // 该弧所指向的顶点的位置
struct ArcNode *nextarc; // 指向下一条弧的指针
InfoType *info; // 该弧相关信息的指针
} ArcNode;
typedef struct VNode{
VertexType data; // 顶点信息
ArcNode *firstarc; // 指向第一条依附该顶点的弧
} VNode, AdjList[MAX_VERTEX_NUM];
typedef struct{
AdjList vertices;
int vexnum, arcnum;
int kind; // 图的种类标志
} ALGraph;正确答案B
解析详情
在有向图的邻接表中,u 的出度可顺着第 k 个表头统计,但入度必须扫描所有顶点的弧链才能知道有多少弧指向 u。总工作量由扫描全部弧主导,因此是 O(e)。
第 14 题(单选题,2 分)
给定一个简单有向图 G,判断其中是否存在环路的下列说法哪个最准确?()
正确答案D
解析详情
DFS 可以用回边判环,BFS 也常借助拓扑排序判环,二者都能在线性复杂度内完成。题目没有限定图规模、存储方式和实现细节,无法据此断定谁一定更快,所以选“不确定”。
第 15 题(单选题,2 分)
从顶点 v1 开始遍历下图 G 得到顶点访问序列,在下面所给的 4 个序列中符合广度优先的序列有几个?( ) {v1 v2 v3 v4 v5},{v1 v2 v4 v3 v5},{v1 v4 v2 v3 v5},{v1 v2 v4 v5 v3}

正确答案B
解析详情
需结合图片确认:从 v1 出发时,v2 和 v4 属于第一层,v3 和 v5 在下一层。BFS 必须先访问完同层结点,所以 {v1,v2,v3,v4,v5} 不可能出现,其余 3 个序列可由不同邻接访问顺序得到。
判断题
第 1 题(判断题,2 分)
小杨这学期准备参加GESP的7级考试,其中有关于三角函数的内容,他能够通过下面的代码找到结束循环的角度值。()
int main()
{
double x;
do {
cin >> x;
x = x / 180 * 3.14;
} while (int(sin(x) * sin(x) + cos(x) * cos(x)) == 1);
cout << " // " << sin(x) << " " << cos(x);
cout << endl;
return 0;
}正确答案正确
解析详情
理论上 sin²x+cos²x=1,但程序把角度换成弧度时用了 3.14,不是精确的 π。某些输入会使表达式略小于 1,int 截断后变成 0,从而跳出循环,所以确实可能找到结束循环的角度值。
第 2 题(判断题,2 分)
小杨在开发画笔刷小程序(applet),操作之一是选中黄颜色,然后在下面的左图的中间区域双击后,就变成了右图。这个操作可以用图的泛洪算法来实现。()


正确答案正确
解析详情
双击中间区域后,程序会从起点向四周扩展,把与起点连通且颜色相同的区域整体替换成目标颜色,这正是 flood fill 的典型应用。
第 3 题(判断题,2 分)
假设一棵完全二叉树共有 N 个节点,则树的深度为 。()
正确答案错误
解析详情
完全二叉树有 N 个结点时,深度应为 ⌊log2N⌋+1。题目直接写成 log(N)+1,既缺少以 2 为底,也少了向下取整,因此不正确。
第 4 题(判断题,2 分)
给定一个数字序列 A1, A2, A3, ..., An,要求 i 和 j (1<=i<=j<=n),使 A1+...+Aj 最大,可以使用动态规划方法来求解。()
正确答案正确
解析详情
无论按题面理解为前缀和最大,还是常见的区间和最优问题,都可以把“以某位置结尾的最优值”作为状态递推。动态规划能在线性时间内完成求解。
第 5 题(判断题,2 分)
若变量 x 为 double 类型正数,则 。()
正确答案正确
解析详情
对正数 x 有 log(exp(x))=x。又因为 x>0 时恒有 x>log10(x),例如 0<x<1 时右边为负,x≥1 时 x 的增长也远快于十进对数,所以不等式成立。
第 6 题(判断题,2 分)
简单有向图有 n 个顶点和 e 条弧,可以用邻接矩阵或邻接表来存储,二者求节点 u 的度的时间复杂度一样。()
正确答案错误
解析详情
邻接矩阵求某点的度通常要扫描整行甚至整列,复杂度是 O(n)。邻接表中出度可按链表统计,入度若无额外数组往往要扫描全部弧,复杂度更接近 O(e),二者并不一样。
第 7 题(判断题,2 分)
某个哈希表键值 x 为整数,为其定义哈希函数 H(x)=x%p ,则 p 选择素数时不会产生冲突。()
正确答案错误
解析详情
把模数 p 取成素数只能改善分布,不能保证无冲突。只要两个整数相差 p 的倍数,例如 1 和 p+1,就会得到同一个哈希值。
第 8 题(判断题,2 分)
动态规划只要推导出状态转移方程,就可以写出递归程序来求出最优解。()
正确答案错误
解析详情
有状态转移方程只是第一步,还必须有明确的边界、计算顺序或记忆化机制。若直接写成普通递归而不记忆,往往会出现大量重复计算,不能视为有效的动态规划实现。
第 9 题(判断题,2 分)
广度优先搜索(BFS)能够判断图是否连通。()
正确答案正确
解析详情
从任意一个起点做 BFS,若遍历结束后所有顶点都被访问到,则图连通;若仍有未访问顶点,则图不连通。因此 BFS 可以用来判断连通性。
第 10 题(判断题,2 分)
在C++中,如果定义了构造函数,则创建对象时先执行完缺省的构造函数,再执行这个定义的构造函数。()
正确答案错误
解析详情
创建对象时会直接调用与实参匹配的构造函数,并不会先执行一遍缺省构造函数再执行自定义构造函数。只有成员对象或基类子对象才会按各自规则先构造。