Logo

2025年3月 GESP C++ 7级

GESP · 7级 · 2025-03

60:00
满分 100
时长 60 分钟
27

2025年3月 GESP C++ 7级认证考试真题(含编程操作题部分)

答题卡 已答 0/27
已答 正确 错误 编程题

单选题(共 15 题,每题 2 分)

1

下列哪个选项是C++中的关键字?

2

下面代码输出的是()

int main() {
    int a = 5, b = 2;
    cout << (a >> b) << endl;
}
3

以下代码的输出是什么?

int main() {
    int a = 10;
    int *p = &a;
    int *&q = p;
    *q = 20;
    cout << a << endl;
    return 0;
}
4

下面代码输出的是()

int main() {
    int arr[5] = {1, 2, 3, 4, 5};
    int *p = arr + 2;
    cout << *p << endl;
    return 0;
}
5

下列关于排序的说法,正确的是( )。

6

下面关于C++类构造和析构函数的说法,错误的是( )。

7

下列关于树和图的说法,错误的是( )。

8

是个神奇的数字,因为它是由两个数 和 拼接⽽成,⽽且 。小杨决定写个程序找找
小于 的正整数中共有多少这样神奇的数字。下面程序横线处应填入的是( )。

#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;
}
9

给定一个无向图,图的节点编号从 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);
    }

39

vector<bool> visited(n, false);
// 从节点 0 开始DFS遍历
DFS(0, graph, visited);
return 0;
}
10

给定一个整数数组 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;
}
11

给定一个整数数组 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;
}
12

给定两个无向图
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;
}
13

给定一个 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;
}
14

给定一个整数数组 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;
}
15

在哈希表的实现中,冲突解决是一个重要的问题。以下哪种方法 不是 常见的哈希表冲突解决策略?

判断题(共 10 题,每题 2 分)

16

在C++语法中,表达式1e6、1000000和10^6的值是相同的。

17

在C++语⾔中,函数调用前必须有函数声明或定义。

18

快速排序一般是不稳定的。

19

long long类型能表达的数都能使用double类型精确表达。

20

使用math.h或cmath头文件中的函数,表达式cos(60)的结果类型为double、值约为0.5。

21

一颗 层的满二叉树,一定有 个结点。

22

邻接表和邻接矩阵都是图的存储形式。为了操作时间复杂度考虑,同一个图可以同时维护两种存储形式。

23

⼦类对象包含⽗类的所有成员(包括私有成员)。从⽗类继承的私有成员也是⼦类的成员,因此⼦类可以直
接访问。

24

动态规划算法通常有递归实现和递推实现。但由于递归调用在运行时会由于层数过多导致程序崩溃,有些动
态规划算法只能用递推实现。

25

按照下面的规则生成一棵二叉树:以一个⼈为根节点,其⽗亲为左⼦节点,母亲为右⼦节点。对其⽗亲、
母亲分别用同样规则生成左⼦树和右⼦树。以此类推,记录30代的直系家谱,则这是一棵满二叉树。

编程操作题(共 2 题,共 50 分)

26
编程操作题 25分

试题名称:图上移动

时间限制:1.0 s | 内存限制:512.0 MB

题目描述

⼩ A 有⼀张包含 个结点与 条边的⽆向图,结点以 标号。⼩ A 会从图上选择⼀个结点作为起点,每⼀
步移动到某个与当前⼩ A 所在结点相邻的结点。对于每个结点 ( ),⼩ A 想知道从结点 出发恰好移动
步之后,⼩ A 可能位于哪些结点。由于满⾜条件的结点可能有很多,你只需要求出这些结点的数量。

输入格式

第⼀⾏,三个正整数 ,分别表⽰⽆向图的结点数与边数,最多移动的步数。
接下来 ⾏,每⾏两个正整数 ,表⽰图中的⼀条连接结点 与 的⽆向边。

输出格式

共 ⾏,第 ⾏( )包含 个整数,第 个整数( )表⽰从结点 出发恰好移动 步之后可能位
于的结点数量。

数据范围

对于 % 的测试点,保证 。
对于另外 % 的测试点,保证 , 。
对于所有测试点,保证 , , , 。

27
编程操作题 25分

试题名称:等价消除

时间限制:1.0 s | 内存限制:512.0 MB

题目描述

⼩ A 有⼀个仅包含⼩写英⽂字母的字符串 。
对于⼀个字符串,如果能通过每次删去其中两个相同字符的⽅式,将这个字符串变为空串,那么称这个字符串是可
以被等价消除的。
⼩ A 想知道 有多少⼦串是可以被等价消除的。
⼀个字符串 是 的⼦串,当且仅当删去 的某个可以为空的前缀和某个可以为空的后缀之后,可以得到 。

输入格式

第⼀⾏,⼀个正整数 ,表⽰字符串 的长度。
第⼆⾏,⼀个仅包含⼩写英⽂字母的字符串 。

输出格式

⼀⾏,⼀个整数,表⽰答案。

数据范围

对于 % 的测试点,保证 中仅包含 a 和 b 两种字符。
对于另外 % 的测试点,保证 。
对于所有测试点,保证 。

已答 0/27