2025年3月CCF—GESP(C++七级)编程能力等级认证试卷
七级
2025
2026-03-27 15:32:11
97次
一、单选题
给定两个无向图 G1和 G2 ,判断它们是否同构。图的同构是指两个图的节点可以通过某种重新编号的方式完全匹配,且边的连接关系一致。
为了简化问题,假设图的节点编号从 0 到 n-1,并且图的边以邻接表的形式给出。下面程序中横线处应该给出的是?( )
#include <iostream>
#include <vector>
#include <map>
#include <algorithm>
using namespace std;
string graphHash(vector<vector<int>>& graph) {
vector<string> nodeHashes(graph.size());
for (int i = 0; i < graph.size(); i++) {
vector<int> neighbors = graph[i];
sort(neighbors.begin(), neighbors.end());
string hash;
for (int neighbor : neighbors) {
_______________________________
}
nodeHashes[i] = hash;
}
sort(nodeHashes.begin(), nodeHashes.end());
string finalHash;
for (string h : nodeHashes) {
finalHash += h + ";";
}
return finalHash;
}
int main() {
int n;
cin >> n;
vector<vector<int>> G1(n);
for (int i = 0; i < n; i++) {
int k;
while (cin >> k) {
G1[i].push_back(k);
if (cin.get() == '\n') break;
}
}
vector<vector<int>> G2(n);
for (int i = 0; i < n; i++) {
int k;
while (cin >> k) {
G2[i].push_back(k);
if (cin.get() == '\n') break;
}
}
string hash1 = graphHash(G1);
string hash2 = graphHash(G2);
if (hash1 == hash2) {
cout << "YES" << endl;
} else {
cout << "NO" << endl;
}
return 0;
} | A. hash += to_string(neighbor); |
B. hash += to_string(neighbors); |
| C. hash += to_string(neighbor) + ","; |
D. hash -= to_string(neighbors); |
【知识点】 CCF—GESP C++七级
给定一个无向图,图的节点编号从 0 到 n - 1,图的边以邻接表的形式给出。
下面的程序使用深度优先搜索(DFS)遍历该图,并输出遍历的节点顺序。横线处应该填入的是?( )
#include <iostream>
#include <vector>
#include <stack>
using namespace std;
void DFS(int start, vector<vector<int>>& graph, vector<bool>& visited) {
stack<int> s;
s.push(start);
visited[start] = true;
while (!s.empty()) {
int node = s.top();
s.pop();
cout << node << " "; // 输出当前节点
// 遍历邻接节点
for (int neighbor : graph[node]) {
if (!visited[neighbor]) {
__________________
__________________
}
}
}
}
int main() {
int n, m;
cin >> n >> m;
vector<vector<int>> graph(n);
for (int i = 0; i < m; i++) {
int u, v;
cin >> u >> v;
graph[u].push_back(v);
graph[v].push_back(u);
}
vector<bool> visited(n, false);
// 从节点 0 开始 DFS遍历
DFS(0, graph, visited);
return 0;
} | A. visited[neighbor] = true; s.push(neighbor-1); |
B. visited[neighbor] = true; s.push(neighbor+1); |
| C. visited[neighbor] = false; s.push(neighbor); |
D. visited[neighbor] = true; s.push(neighbor); |
【知识点】 CCF—GESP C++七级
给定一个 m×n的二维网格 grid,每个格子中有一个非负整数。
请找出一条从左上角 (0, 0) 到右下角 (m-1, n-1) 的路径,使得路径上的数字总和最小。每次只能向右或向下移动。
横线处应该填入的是?( )
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int minPathSum(vector<vector<int>>& grid) {
int m = grid.size();
int n = grid[0].size();
vector<vector<int>> dp(m, vector<int>(n, 0));
dp[0][0] = grid[0][0];
for (int j = 1; j < n; j++) {
dp[0][j] = dp[0][j - 1] + grid[0][j];
}
for (int i = 1; i < m; i++) {
dp[i][0] = dp[i - 1][0] + grid[i][0];
}
for (int i = 1; i < m; i++) {
for (int j = 1; j < n; j++) {
________________________________
}
}
return dp[m - 1][n - 1];
}
int main() {
int m, n;
cin >> m >> n;
vector<vector<int>> grid(m, vector<int>(n));
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
cin >> grid[i][j];
}
}
int result = minPathSum(grid);
cout << result << endl;
return 0;
} | A. dp[i][j] = min(dp[i - 1][j], dp[i][j - 1]) + grid[i][1]; |
B. dp[i][j] = min(dp[i - 1][j], dp[i][j - 1]) + grid[i][j]; |
| C. dp[i][j] = min(dp[i - 1][j], dp[i][j]) + grid[i][j]; |
D. dp[i][j] = min(dp[i][j], dp[i][j - 1]) + grid[i][j]; |
【知识点】 CCF—GESP C++七级
给定一个整数数组 nums,找到其中最长的严格上升子序列的长度。
子序列是指从原数组中删除一些元素(或不删除)后,剩余元素保持原有顺序的序列。
下面的程序横线处应该填入的是?( )
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int lengthOfLIS(vector<int>& nums) {
int n = nums.size();
if (n == 0) return 0;
vector<int> dp(n, 1);
for (int i = 1; i < n; i++) {
for (int j = 0; j < i; j++) {
if (nums[i] > nums[j]) {
_________________________
}
}
}
return *max_element(dp.begin(), dp.end());
}
int main() {
int n;
cin >> n;
vector<int> nums(n);
for (int i = 0; i < n; i++) {
cin >> nums[i];
}
int result = lengthOfLIS(nums);
cout << result << endl;
return 0;
} | A. dp[i] = max(dp[i], dp[j]); |
B. dp[i] = max(dp[i+1], dp[j] + 1); |
| C. dp[i] = max(dp[i], dp[j] - 1); |
D. dp[i] = max(dp[i], dp[j] + 1); |
【知识点】 CCF—GESP C++七级
2025 是个神奇的数字,因为它是由两个数 20 和 25 拼接而成,而且 2025 =(20+25)2 。
小杨决定写个程序找找小于 N 的正整数中共有多少这样神奇的数字。下面程序横线处应填入的是?( )
#include <string>
int count_miracle(int N) {
int cnt = 0;
for (int n = 1; n * n < N; n++) {
int n2 = n * n;
std::string s = std::to_string(n2);
for (int i = 1; i < s.length(); i++)
if (s[i] != '0') {
std::string sl = s.substr(0, i);
std::string sr = s.substr(i);
int nl = std::stoi(sl);
int nr = std::stoi(sr);
if (_________) // 在此处填入选项
cnt++;
}
}
return cnt;
} | A. nl + nr == n |
B. nl + nr == n2 |
| C. (nl + nr) * (nl + nr) == n |
D. (nl + nr) ^ 2 == n2 |
【知识点】 CCF—GESP C++七级
给定一个整数数组 nums,找到其中最长的严格上升子序列的长度。
子序列是指从原数组中删除一些元素(或不删除)后,剩余元素保持原有顺序的序列。
该程序的时间复杂度为?( )
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int lengthOfLIS(vector<int>& nums) {
int n = nums.size();
if (n == 0) return 0;
vector<int> dp(n, 1);
for (int i = 1; i < n; i++) {
for (int j = 0; j < i; j++) {
if (nums[i] > nums[j]) {
_________________________
}
}
}
return *max_element(dp.begin(), dp.end());
}
int main() {
int n;
cin >> n;
vector<int> nums(n);
for (int i = 0; i < n; i++) {
cin >> nums[i];
}
int result = lengthOfLIS(nums);
cout << result << endl;
return 0;
} | A. O(n2) |
B. O(n) |
| C. O(log(n)) |
D. O(nlog(n)) |
【知识点】 CCF—GESP C++七级
给定一个整数数组 nums,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。
下面横线处应该填入的是?( )
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int maxSubArray(vector<int>& nums) {
int n = nums.size();
if (n == 0) return 0;
vector<int> dp(n, 0);
dp[0] = nums[0];
int maxSum = dp[0];
for (int i = 1; i < n; i++) {
_______________________________
maxSum = max(maxSum, dp[i]);
}
return maxSum;
}
int main() {
int n;
cin >> n;
vector<int> nums(n);
for (int i = 0; i < n; i++) {
cin >> nums[i];
}
int result = maxSubArray(nums);
cout << result << endl;
return 0;
} | A. dp[i] = max(nums[i+1], dp[i - 1] + nums[i]); |
B. dp[i] = max(nums[i], dp[i - 1] + nums[i]); |
| C. dp[i] = max(nums[i], dp[i + 1] + nums[i]); |
D. dp[i] = max(nums[i], dp[i - 1] + nums[i+1]); |
【知识点】 CCF—GESP C++七级
二、判断题
三、编程题
等价消除
时间限制:1 s,内存限制:512 MB
【问题描述】
小 A 有一个仅包含小写英文字母的字符串 。
对于一个字符串,如果能通过每次删去其中两个相同字符的方式,将这个字符串变为空串,那么称这个字符串是可以被等价消除的。
小 A 想知道 S 有多少子串是可以被等价消除的。
一个字符串 S' 是 S 的子串,当且仅当删去 S 的某个可以为空的前缀和某个可以为空的后缀之后,可以得到 S'。
【输入描述】
第一行,一个正整数 |S|,表示字符串 S 的长度。
第二行,一个仅包含小写英文字母的字符串 S。
【输出描述】
一行,一个整数,表示答案。
【样例输入1】
7 aaaaabb
【样例输出1】
9
【样例输入2】
9 babacabab
【样例输出2】
2
【数据范围】
对于 20% 的测试点,保证 S 中仅包含 a 和 b 两种字符。
对于另外 20% 的测试点,保证 1<=|S|<=2000。
对于所有测试点,保证 1<=|S|<=200000。
【知识点】 CCF—GESP C++七级
图上移动
时间限制:1 s,内存限制:512 MB
【问题描述】
小 A 有一张包含 个n 结点与 m 条边的无向图,结点以 1、2、……、n 标号。
小 A 会从图上选择一个结点作为起点,每一步移动到某个与当前小 A 所在结点相邻的结点。
对于每个结点 i(1<=i<=n),小 A 想知道从结点 i 出发恰好移动步1、2、……、k 之后,小 A 可能位于哪些结点。
由于满足条件的结点可能有很多,你只需要求出这些结点的数量。
【输入描述】
第一行,三个正整数 n、m、k,分别表示无向图的结点数与边数,最多移动的步数。
接下来 m 行,每行两个正整数 ui、vi,表示图中的一条连接结点 ui 与 vi 的无向边。
【输出描述】
共 n 行,第 i 行(1<=i<=n )包含 k 个整数,第 j 个整数( 1<=j<=k)表示从结点 i 出发恰好移动 j 步之后可能位于的结点数量。
【样例输入1】
4 4 3 1 2 1 3 2 3 3 4
【样例输出1】
2 4 4 2 4 4 3 3 4 1 3 3
【数据范围】
对于 20% 的测试点,保证 k=1。
对于另外 20% 的测试点,保证 1<=n<=50,1<=m<=50 。
对于所有测试点,保证 1<=n<=500,1<=m<=500 ,1<=k<=20 ,1<=ui、vi<=n 。
【知识点】 CCF—GESP C++七级
