下列哪个选项是C++中的关键字?
B:class 是 C++ 语言关键字(用于定义类);function、method、object 都不是 C++ 关键字。故 B 正确。
下面代码输出的是( )
01int main() { 02 int a = 5, b = 2; 03 cout << (a >> b) << endl; 04}
A:a>>b 即 5>>2,5 的二进制是 101,右移两位后低位的两位被丢弃,得到 001 即十进制 1,等价于 5÷4 取整,故不是 2 或 5。
以下代码的输出是什么?
01int main() { 02 int a = 10; 03 int *p = &a; 04 int *&q = p; 05 *q = 20; 06 cout << a << endl; 07 return 0; 08}
B:q 是 p 的引用(指针的引用),*q=20 等价于通过 p 修改其指向的对象,因此 a 的值从 10 变为 20。故 B 正确。
下面代码输出的是( )
01int main() { 02 int arr[5] = {1, 2, 3, 4, 5}; 03 int *p = arr + 2; 04 cout << *p << endl; 05 return 0; 06}
C:p=arr+2 指向数组第 3 个元素(下标为 2,即 arr[2]),解引用 *p 得到该元素的值 3,而不是 1 或 2,故选 C。
下列关于排序的说法,正确的是( )。
B:归并排序合并时相等元素保持原先后顺序,通常稳定;选择并非最快,快排最差 O(n²),插入最好 O(n),故 B 正确。故选 B。
下面关于C++类构造和析构函数的说法,错误的是( )。
B:仅当通过基类指针删除派生类对象(多态析构)时才要求析构函数声明为虚;并非任何情况下都必须为虚,故 B 说法错误,其余正确,故选 B。
下列关于树和图的说法,错误的是( )。
B:树按父子方向定向后是有向无环图,边只从父指向子、不存在反向边,无法构成双向可达路径,故不是强连通图,B 说法错误,故选 B,故选 B。
2025是个神奇的数字,因为它是由两个数20和25拼接而成,而且。小杨决定写个程序找找小于的正整数中共有多少这样神奇的数字。下面程序横线处应填入的是( )。
01#include <string> 02int count_miracle(int N) { 03 int cnt = 0; 04 for (int n = 1; n * n < N; n++) { 05 int n2 = n * n; 06 std::string s = std::to_string(n2); 07 for (int i = 1; i < s.size(); i++) 08 if (s[i] != '0') { 09 std::string sl = s.substr(0, i); 10 std::string sr = s.substr(i); 11 int nl = std::stoi(sl); 12 int nr = std::stoi(sr); 13 if (____________) // 在此处填入选项 14 cnt++; 15 } 16 } 17 return cnt; 18}
A:神奇数满足 (nl+nr)²=n²,即 nl+nr=n,代码枚举 n(n² 为候选)后判断拆分两半之和是否等于 n,故选 A,故选 A。
给定一个无向图,图的节点编号从 0 到 n-1,图的边以邻接表的形式给出。下面的程序使用深度优先搜索(DFS)遍历该图,并输出遍历的节点顺序。横线处应该填入的是( )
01#include <iostream> 02#include <vector> 03#include <stack> 04using namespace std; 05void DFS(int start, vector<vector<int>>& graph, vector<bool>& visited) { 06 stack<int> s; 07 s.push(start); 08 visited[start] = true; 09 while (!s.empty()) { 10 int node = s.top(); 11 s.pop(); 12 cout << node << " "; // 输出当前节点 13 // 遍历邻接节点 14 for (int neighbor : graph[node]) { 15 if (!visited[neighbor]) { 16 ____________ 17 ____________ 18 } 19 } 20 } 21} 22int main() { 23 int n, m; 24 cin >> n >> m; 25 vector<vector<int>> graph(n); 26 for (int i = 0; i < m; i++) { 27 int u, v; 28 cin >> u >> v; 29 graph[u].push_back(v); 30 graph[v].push_back(u); 31 } 32 vector<bool> visited(n, false); 33 // 从节点 0 开始DFS遍历 34 DFS(0, graph, visited); 35 return 0; 36}
D:栈式 DFS 需先标记 visited[neighbor]=true 防止重复入栈,再把 neighbor 压入栈顶,两处分别填这两句。
给定一个整数数组 nums,找到其中最长的严格上升子序列的长度。子序列是指从原数组中删除一些元素(或不删除)后,剩余元素保持原有顺序的序列。下面的程序横线处应该填入的是( )
01#include <iostream> 02#include <vector> 03#include <algorithm> 04using namespace std; 05int lengthOfLIS(vector<int>& nums) { 06 int n = nums.size(); 07 if (n == 0) return 0; 08 vector<int> dp(n, 1); 09 for (int i = 1; i < n; i++) { 10 for (int j = 0; j < i; j++) { 11 if (nums[i] > nums[j]) { 12 ____________ 13 } 14 } 15 } 16 return *max_element(dp.begin(), dp.end()); 17} 18int main() { 19 int n; 20 cin >> n; 21 vector<int> nums(n); 22 for (int i = 0; i < n; i++) { 23 cin >> nums[i]; 24 } 25 int result = lengthOfLIS(nums); 26 cout << result << endl; 27 return 0; 28}
D:LIS 转移:若 nums[j]<nums[i],用 dp[j]+1 更新 dp[i],即 dp[i]=max(dp[i], dp[j]+1)。
给定一个整数数组 nums,找到其中最长的严格上升子序列的长度。子序列是指从原数组中删除一些元素(或不删除)后,剩余元素保持原有顺序的序列。该程序的时间复杂度为( )
01#include <iostream> 02#include <vector> 03#include <algorithm> 04using namespace std; 05int lengthOfLIS(vector<int>& nums) { 06 int n = nums.size(); 07 if (n == 0) return 0; 08 vector<int> dp(n, 1); 09 for (int i = 1; i < n; i++) { 10 for (int j = 0; j < i; j++) { 11 if (nums[i] > nums[j]) { 12 ____________ 13 } 14 } 15 } 16 return *max_element(dp.begin(), dp.end()); 17} 18int main() { 19 int n; 20 cin >> n; 21 vector<int> nums(n); 22 for (int i = 0; i < n; i++) { 23 cin >> nums[i]; 24 } 25 int result = lengthOfLIS(nums); 26 cout << result << endl; 27 return 0; 28}
A:外层 i 从 1 到 n、内层 j 从 0 到 i−1,双层循环约执行 n²/2 次,时间复杂度为 O(n²),不是 O(n) 或 O(log n)。
给定两个无向图
和 ,判断它们是否同构。图的同构是指两个图的节点可以通过某种重新编号的方式完全匹配,且边的连接关系一致。
为了简化问题,假设图的节点编号从 0 到 n-1,并且图的边以邻接表的形式给出。下面程序中横线处应该给出的是( )
01#include <iostream> 02#include <vector> 03#include <map> 04#include <algorithm> 05using namespace std; 06string graphHash(vector<vector<int>>& graph) { 07 vector<string> nodeHashes(graph.size()); 08 for (int i = 0; i < graph.size(); i++) { 09 vector<int> neighbors = graph[i]; 10 sort(neighbors.begin(), neighbors.end()); 11 string hash; 12 for (int neighbor : neighbors) { 13 ____________ 14 } 15 nodeHashes[i] = hash; 16 } 17 sort(nodeHashes.begin(), nodeHashes.end()); 18 string finalHash; 19 for (string h : nodeHashes) { 20 finalHash += h + ";"; 21 } 22 return finalHash; 23} 24int main() { 25 int n; 26 cin >> n; 27 vector<vector<int>> G1(n); 28 for (int i = 0; i < n; i++) { 29 int k; 30 while (cin >> k) { 31 G1[i].push_back(k); 32 if (cin.get() == '\n') break; 33 } 34 } 35 vector<vector<int>> G2(n); 36 for (int i = 0; i < n; i++) { 37 int k; 38 while (cin >> k) { 39 G2[i].push_back(k); 40 if (cin.get() == '\n') break; 41 } 42 } 43 string hash1 = graphHash(G1); 44 string hash2 = graphHash(G2); 45 if (hash1 == hash2) { 46 cout << "YES" << endl; 47 } else { 48 cout << "NO" << endl; 49 } 50 return 0; 51}
C:拼接每个邻居编号并加逗号分隔,避免 1,2 与 12 等不同邻居列表产生相同哈希;A 无分隔符、B 对 vector 用 to_string 不合法、D 语法错误。
给定一个 的二维网格 grid,每个格子中有一个非负整数。请找出一条从左上角 到右下角 的路径,使得路径上的数字总和最小。每次只能向右或向下移动。横线处应该填入的是( )
01#include <iostream> 02#include <vector> 03#include <algorithm> 04using namespace std; 05int minPathSum(vector<vector<int>>& grid) { 06 int m = grid.size(); 07 int n = grid[0].size(); 08 vector<vector<int>> dp(m, vector<int>(n, 0)); 09 dp[0][0] = grid[0][0]; 10 for (int j = 1; j < n; j++) { 11 dp[0][j] = dp[0][j - 1] + grid[0][j]; 12 } 13 for (int i = 1; i < m; i++) { 14 dp[i][0] = dp[i - 1][0] + grid[i][0]; 15 } 16 for (int i = 1; i < m; i++) { 17 for (int j = 1; j < n; j++) { 18 ____________ 19 } 20 } 21 return dp[m - 1][n - 1]; 22} 23int main() { 24 int m, n; 25 cin >> m >> n; 26 vector<vector<int>> grid(m, vector<int>(n)); 27 for (int i = 0; i < m; i++) { 28 for (int j = 0; j < n; j++) { 29 cin >> grid[i][j]; 30 } 31 } 32 int result = minPathSum(grid); 33 cout << result << endl; 34 return 0; 35}
B:最小路径和转移 dp[i][j]=min(dp[i-1][j], dp[i][j-1])+grid[i][j],加上当前格子的值,故选 B。
给定一个整数数组 nums,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。下面横线处应该填入的是( )
01#include <iostream> 02#include <vector> 03#include <algorithm> 04using namespace std; 05int maxSubArray(vector<int>& nums) { 06 int n = nums.size(); 07 if (n == 0) return 0; 08 vector<int> dp(n, 0); 09 dp[0] = nums[0]; 10 int maxSum = dp[0]; 11 for (int i = 1; i < n; i++) { 12 ____________ 13 maxSum = max(maxSum, dp[i]); 14 } 15 return maxSum; 16} 17int main() { 18 int n; 19 cin >> n; 20 vector<int> nums(n); 21 for (int i = 0; i < n; i++) { 22 cin >> nums[i]; 23 } 24 int result = maxSubArray(nums); 25 cout << result << endl; 26 return 0; 27}
B:最大子段和转移 dp[i]=max(nums[i], dp[i-1]+nums[i]):要么从 nums[i] 重新开始,要么接上以 i−1 结尾的段。
在哈希表的实现中,冲突解决是一个重要的问题。以下哪种方法 不是 常见的哈希表冲突解决策略?
D:链地址法、开放地址法、二次哈希法都是常见的哈希冲突解决策略;二分查找是查找算法,不属于冲突处理策略,因此本题选 D。故 D 正确。
在C++语法中,表达式 1e6、1000000 和 10^6 的值是相同的。
错。10^6 在 C++ 中 ^ 是按位异或:10 XOR 6 = 1010₂ XOR 0110₂ = 1100₂ = 12,与 1e6、1000000 不同。
在C++语言中,函数调用前必须有函数声明或定义。
对。函数在调用前必须有函数声明或完整定义,否则编译器不认识该函数名会报错;函数定义可以在调用之后,但声明必须先于调用出现。故正确,故对。
快速排序一般是不稳定的。
对。快速排序以基准划分区间时会跨越式交换元素,可能把相等的两个元素换到彼此之后,改变它们排序前后的相对顺序,因此一般不稳定,故对。
long long 类型能表达的数都能使用 double 类型精确表达。
错。double 只有约 53 位有效二进制位,大于 2⁵³ 的 long long 整数无法被 double 精确表示,会损失精度。
使用 math.h 或 cmath 头文件中的函数,表达式 cos(60) 的结果类型为 double 、值约为 0.5 。
错。cos 的参数是弧度制:cos(60) 求 60 弧度的余弦约 −0.952,不是 cos60°=0.5;要算角度需先转弧度,故错。
一颗层的满二叉树,一定有个结点。
对。满二叉树每一层的结点数都比上一层翻倍,即第 k 层有 2^(k−1) 个结点,N 层总结点数为 2⁰+2¹+…+2^(N−1)=2^N−1,公式正确。
邻接表和邻接矩阵都是图的存储形式。为了操作时间复杂度考虑,同一个图可以同时维护两种存储形式。
对。同一张图可以同时维护邻接表和邻接矩阵两种存储:遍历顶点的边用邻接表更快、判断两点是否相邻用矩阵更快,以空间换时间完全可行,故对。
子类对象包含父类的所有成员(包括私有成员)。从父类继承的私有成员也是子类的成员,因此子类可以直接访问。
错。子类对象在内存上确实包含父类的私有成员,但私有成员的访问权限属于父类,子类只能通过父类提供的公有接口间接访问,不能直接访问,故错。
动态规划算法通常有递归实现和递推实现。但由于递归调用在运行时会由于层数过多导致程序崩溃,有些动态规划算法只能用递推实现。
对。递归层数过深会耗尽调用栈导致程序崩溃,某些动态规划问题递归深度过大,只能采用自底向上的递推实现(无法用递归),故说法正确,故对。
按照下面的规则生成一棵二叉树:以一个人为根节点,其父亲为左子节点,母亲为右子节点。对其父亲、母亲分别用同样规则生成左子树和右子树。以此类推,记录30代的直系家谱,则这是一棵满二叉树。
错。30 代直系家谱中祖先可能重复(近亲婚配使同一人出现在多条路径上),各层人数不满足逐层翻倍,因此并不是满二叉树,说法错误,故错。