定义变量 double x,如果下面代码输入为 100,输出最接近( )。
01#include <iostream> 02#include <string> 03#include <cmath> 04#include <vector> 05using namespace std; 06 07int main() 08{ 09 double x; 10 11 cin >> x; 12 cout << log10(x) - log2(x) << endl; 13 14 cout << endl; 15 return 0; 16}
B:log10(100)=2;log2(100)=log10(100)/log10(2)≈2/0.3010≈6.64,输出 2−6.64≈−4.64,最接近 −5。
对于下面动态规划方法实现的函数,以下选项中最适合表达其状态转移函数的为( )。
01int s[MAX_N], f[MAX_N][MAX_N]; 02int stone_merge(int n, int a[]) { 03 for (int i = 1; i <= n; i++) 04 s[i] = s[i - 1] + a[i]; 05 for (int i = 1; i <= n; i++) 06 for (int j = 1; j <= n; j++) 07 if (i == j) 08 f[i][j] = 0; 09 else 10 f[i][j] = MAX_F; 11 for (int l = 1; l < n; l++) 12 for (int i = 1; i <= n - l; i++) { 13 int j = i + l; 14 for (int k = i; k < j; k++) 15 f[i][j] = min(f[i][j], f[i][k] + f[k + 1][j] + s[j] - s[i - 1]); 16 } 17 return f[1][n]; 18}
D:这是石子合并区间 DP。转移式 f[i][j]=min(f[i][k]+f[k+1][j])+s[j]−s[i−1],s[j]−s[i−1] 即 Σa[i..j] 为本次合并代价;A 把 f(i,j) 写进 min 内部,不是标准转移式。
下面代码可以用来求最长上升子序列(LIS)的长度,如果输入是:5 1 7 3 5 9,则输出是( )。
01int a[2023], f[2023]; 02int main() 03{ 04 int n,i,j,ans = -1; 05 06 cin>>n; 07 for( i=1; i<=n; i++){ 08 cin >> a[i]; 09 f[i] = 1; 10 } 11 12 for( i=1; i<=n; i++) 13 for( j=1; j<i; j++) 14 if(a[j] < a[i]) 15 f[i] = max(f[i], f[j]+1); 16 for( i=1; i<=n; i++){ 17 ans = max(ans, f[i]); 18 cout << f[i] << " "; 19 } 20 21 cout << ans << endl; 22 return 0; 23}
B:n=5,a=[1,7,3,5,9],f 初值全 1。f[2]=2(1<7);f[3]=2(1<3);f[4]=3(1<5、3<5);f[5]=4(7<9、5<9),输出 f 序列 1 2 2 3 4,ans=4。
C++ 语言中,下列关于关键字 static 的描述不正确的是( )。
C:static 成员函数、常量静态成员类外初始化、静态对象 main 前后构造析构都正确;常量静态成员若只作编译期常量使用可无存储,地址并非总能访问,故 C 错。
G 是一个非连通无向图,共有 条边,则该图至少有( )个顶点。
D:非连通则至少两个连通分量。9 个顶点可分成 K8(C(8,2)=28 条边)加 1 个孤立顶点;8 个顶点非连通最多 C(7,2)=21 条边,故最少 9 个顶点。
哈希表长 ,按照下面的程序依次输入 4 17 28 30 4,则最后的 存入哪个位置?( )
01#include <iostream> 02#include <string> 03#include <cmath> 04#include <vector> 05using namespace std; 06 07const int N=31; 08int htab[N],flag[N]; 09int main() 10{ 11 int n,x,i,j,k; 12 13 cin >> n; 14 for(i=0; i<n; i++){ 15 cin >> x; 16 k=x%13; 17 while(flag[k]) k = (k+1)%13; 18 htab[k]=x; 19 flag[k]=1; 20 } 21 22 for(i=0; i<N; i++) 23 cout << htab[i] << " "; 24 25 cout << endl; 26 return 0; 27}
D:第一个 4 是 n=4,实际插入 17、28、30、4。17%13=4 存 4 号,28%13=2 存 2 号,30 线性探测 4、5 后存 5 号,最后的 4 探测 4、5 均占用落到 6 号。
某二叉树 T 的先序遍历序列为:{A B D F C E G H},中序遍历序列为:{B F D A G E H C},则下列说法中正确的是( )。
B:由先序定根、中序分左右:A 为根,左子树 B(右子 D、D 左子 F),右子树 C(左子 E、E 左右为 G、H);共 4 层高,叶仅 F、G、H 三个,度为 2,选 B。
下面代码段可以求两个字符串 s1 和 s2 的最长公共子串(LCS),下列相关描述不正确的是( )。
01while (cin >> s1 >> s2) 02{ 03 memset(dp, 0, sizeof(dp)); 04 int n1 = strlen(s1), n2 = strlen(s2); 05 for (int i = 1; i <= n1; ++i) 06 for (int j = 1; j <= n2; ++j) 07 if (s1[i - 1] == s2[j - 1]) 08 dp[i][j] = dp[i - 1][j - 1] + 1; 09 else 10 dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]); 11 cout << dp[n1][n2] << endl; 12}
C:dp[i][j] 只依赖左、上、左上三格,可用滚动数组把空间压到 O(min(n1,n2)),O(n²) 空间并非最优;其余描述都正确,故选 C。
图的广度优先搜索中既要维护一个标志数组标志已访问的图的结点,还需哪种结构存放结点以实现遍历?( )
B:BFS 按层扩展,先访问的顶点先扩展其邻点,需用先进先出的队列存放待访问结点,配合访问标志数组防止重复入队;栈、堆、哈希表都不符合。
对关键字序列 {44, 36, 23, 35, 52, 73, 90, 58} 建立哈希表,哈希函数为 h(k)=k%7,执行下面的 Insert 函数,则等概率情况下的平均成功查找长度(即查找成功时的关键字比较次数的均值)为( )。
01#include <iostream> 02#include <string> 03#include <cmath> 04#include <vector> 05using namespace std; 06 07typedef struct Node{ 08 int data; 09 struct Node *next; 10}Node; 11Node* hTab[7]; 12int key[]={44, 36, 23, 35, 52, 73, 90, 58, 0}; 13void Insert() 14{ 15 int i,j; 16 Node *x; 17 18 for(i=0; key[i];i++){ 19 j = key[i] % 7; 20 x=new Node; 21 x->data = key[i]; 22 x->next = hTab[j]; 23 hTab[j] = x; 24 } 25 26 return; 27}
C:链地址法头插。44、36、23、35、52、73、90、58 的桶号 2、1、2、0、3、3、6、2;查找比较次数依次 3、1、2、1、2、1、1、1,共 12 次,平均 12/8=1.5。
学生在读期间所上的某些课程中需要先上其他的课程,所有课程和课程间的先修关系构成一个有向图 G,有向边 <U, V> 表示课程 U 是课程 V 的先修课,则要找到某门课程 C 的全部先修课下面哪种方法不可行?( )
D:把边反向从 C 出发 BFS/DFS 都能遍历全部先修课;动态规划面向最优子结构问题,求先修课集合不是最优化问题,无法用 DP,故不可行。
一棵完全二叉树有 个结点,则叶结点有多少个?( )
C:前 10 层满共 2¹⁰−1=1023 结点,第 11 层有 2023−1023=1000 个叶;第 10 层 512 结点中前 500 个有孩子,其余 12 个也成为叶,共 1012 个。
用下面的邻接表结构保存一个有向图 G,InfoType 和 VertexType 是定义好的类。设 G 有 个顶点、 条弧,则求图 G 中某个顶点 u(其顶点序号为 )的度的算法复杂度是( )。
01typedef struct ArcNode{ 02 int adjvex; // 该弧所指向的顶点的位置 03 struct ArcNode *nextarc; // 指向下一条弧的指针 04 InfoType *info; // 该弧相关信息的指针 05} ArcNode; 06typedef struct VNode{ 07 VertexType data; // 顶点信息 08 ArcNode *firstarc; // 指向第一条依附该顶点的弧 09} VNode, AdjList[MAX_VERTEX_NUM]; 10typedef struct{ 11 AdjList vertices; 12 int vexnum, arcnum; 13 int kind; // 图的种类标志 14} ALGraph;
B:邻接表求出度只需数顶点 u 的弧链表长度,最坏 O(e);求入度要扫描各顶点弧链表统计指向 u 的弧,也以弧数 e 为主,故度为 O(e)。
给定一个简单有向图 G,判断其中是否存在环路的下列说法哪个最准确?( )
D:DFS 判返祖边、BFS 做拓扑排序都能判有向图环,复杂度同为 O(n+e),谁更快取决于图的形态与环的位置,无法一概而论,选不确定。
从顶点 v1 开始遍历下图 G 得到顶点访问序列,在下面所给的 个序列中符合广度优先的序列有几个?( )
{v1 v2 v3 v4 v5},{v1 v2 v4 v3 v5},{v1 v4 v2 v3 v5},{v1 v2 v4 v5 v3}
B:图中 v1 的邻点是 v2、v4,第二层是 v5、v3。BFS 要求第一层先于第二层:序列 1 把第二层的 v3 放在第一层 v4 之前,不符合;序列 2、3、4 均满足,共 3 个。
小杨这学期准备参加 GESP 的 级考试,其中有关于三角函数的内容,他能够通过下面的代码找到结束循环的角度值。( )
01int main() 02{ 03 double x; 04 05 do{ 06 cin >> x; 07 x=x/180*3.14; 08 }while(int(sin(x)*sin(x)+cos(x)*cos(x)) == 1); 09 cout << "//" << sin(x) << " " << cos(x); 10 11 cout << endl; 12 return 0; 13}
对。数学上 sin²x+cos²x≡1,但代码用 3.14 近似 π,浮点舍入使某些角度(如 90°)下该值略小于 1,int() 截断为 0 使循环退出,故能找到终止角度。
小杨在开发画笔刷小程序(applet),操作之一是选中黄颜色,然后在下面的左图的中间区域双击后,就变成了右图。这个操作可以用图的泛洪算法来实现。( )
对。双击选中黄颜色并填充封闭区域,正是从种子点向四周扩散染色的泛洪算法(Flood Fill,可用 BFS/DFS 实现)。故该操作可用泛洪算法完成。
假设一棵完全二叉树共有 个节点,则树的深度为 。( )
错。完全二叉树深度应为 ⌊log₂N⌋+1(向下取整),log(N)+1 不取整;如 N=3 时 log(3)+1≈2.58,实际深度只有 2。
给定一个数字序列 ,要求 和 (),使 最大,可以使用动态规划方法来求解。( )
对。最大子段和是经典 DP:dp[i] 表示以 A[i] 结尾的最大和,转移 dp[i]=max(dp[i-1]+A[i], A[i]),答案取所有 dp 的最大值。
若变量 x 为 double 类型正数,则 log(exp(x)) > log10(x)。( )
对。log(exp(x))=x(log 为自然对数),对任意正数 x 恒有 x>log10(x)(0<x<1 时 log10(x)<0),故不等式成立。
简单有向图有 n 个顶点和 e 条弧,可以用邻接矩阵或邻接表来存储,二者求节点 u 的度的时间复杂度一样。( )
错。邻接矩阵求 u 的度要扫一行 O(n);邻接表无向图数 u 的链表即可 O(deg(u)),有向图求入度还需遍历所有弧,二者复杂度不同。
某个哈希表键值 x 为整数,为其定义哈希函数 H(x)=x%p,则 p 选择素数时不会产生冲突。( )
错。p 取素数只让哈希分布更均匀,不能保证无冲突:如 p=7 时 7 与 14 的哈希值都为 0,仍需开放定址或链地址法解决冲突,仍需定址或拉链解决。
动态规划只要推导出状态转移方程,就可以写出递归程序来求出最优解。( )
错。仅有状态转移方程还不够:还需确定边界条件与初始化值,且直接递归会重复计算大量子问题,要配合记忆化或按阶段递推才能高效求解,配合记忆化才行。
广度优先搜索(BFS)能够判断图是否连通。( )
对。从任一顶点 BFS,用队列逐层扩展并标记访问,若最终能访问全部顶点则图连通,否则不连通,故 BFS 可判断连通性;DFS 从单点出发也能判断连通性。
在 C++ 中,如果定义了构造函数,则创建对象时先执行完缺省的构造函数,再执行这个定义的构造函数。( )
错。一旦用户定义了构造函数,编译器就不再自动生成缺省构造函数;创建对象时只调用定义的那个构造函数,不会先执行缺省构造函数。故说法错误。