2025年3月GESP真题及题解(C++七级): 选择题和判断题(题解)

2025年3月GESP真题及题解(C++七级): 选择题和判断题(题解)


第 1 题

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

A. function

B. class

C. method

D. object

答案:B
解析: class 是C++中用于定义类的关键字,其他选项均为标识符或标准库中的名称,不是关键字。

第 2 题

下面代码输出的是( )

cpp 复制代码
int main() {
    int a = 5, b = 2;
    cout << (a >> b) << endl;
}

A. 1

B. 2

C. 5

D. 10

答案:A
解析: a >> b 表示将 a 的二进制右移 b 位。5 的二进制为 101,右移2位得 1,即1。

第 3 题

以下代码的输出是什么?

cpp 复制代码
int main() {
    int a = 10;
    int *p = &a;
    int *&q = p;
    *q = 20;
    cout << a << endl;
    return 0;
}

A. 10

B. 20

C. 地址值

D. 编译错误

答案:B
解析: q 是指针 p 的引用,修改 *q 即修改 a 的值,因此 a 变为20。

第 4 题

下面代码输出的是( )

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

A. 1

B. 2

C. 3

D. 4

答案:C
解析: arr + 2 指向数组下标为2的元素,即 arr[2],值为3。

第 5 题

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

A. 选择排序是最快的排序算法之一。

B. 归并排序通常是稳定的。

C. 最差情况,NN 个元素做快速排序的时间复杂度为 O(N)。

D. 最好情况,NN 个元素做插入排序的时间复杂度为 O(N 2 ^2 2)。

答案:B
解析: 归并排序在合并时保持相等元素的相对顺序,因此是稳定的。其他选项错误:选择排序不是最快;快速排序最坏为 O(N^2);插入排序最好为 O(N)。

第 6 题

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

A. 构造函数不能声明为虚函数。

B. 析构函数必须声明为虚函数。

C. 类的默认构造函数可以被声明为 private

D. 类的析构函数可以被声明为 private

答案:B
解析: 析构函数只有在类作为基类且需要多态释放时才必须声明为虚函数,并非必须。其他选项正确。

第 7 题

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

A. 树是一种有向无环图,但有向无环图不都是一棵树。

B. 如果把树看做有向图,每个节点指向其子节点,则该图是强连通图。

C. N个顶点且连通的无向图,其最小生成树一定包含 N−1个条边。

D. N+1个顶点、N 条边的有向图,一定不是强连通的。

答案:B
解析: 树作为有向图时,根节点无法到达子节点?实际上根到子有路径,但子到根没有,因此不是强连通。其他选项正确。

第 8 题

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

cpp 复制代码
#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 s1 = s.substr(0, i);
                std::string sr = s.substr(i);
                int n1 = std::stoi(s1);
                int nr = std::stoi(sr);
                if (__________) // 在此处填入选项
                    cnt++;
            }
        }
    }
    return cnt;
}

A. n1 + nr == n

B. n1 + nr == n2

C. (n1 + nr) * (n1 + nr) == n

D. (n1 + nr) ^ 2 == n2

答案:A
解析: 神奇数字满足 n^2 = (n1 + nr)^2,即 n = n1 + nr。程序枚举 nn2 = n*n,拆分后判断 n1 + nr 是否等于 n

第 9 题

给定一个无向图,图的节点编号从 0 到 n−1,图的边以邻接表的形式给出。下面的程序使用深度优先搜索(DFS)遍历该图,并输出遍历的节点顺序。横线处应填入的是( )。

cpp 复制代码
#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);

答案:D
解析: 在DFS非递归实现中,访问邻居时需标记已访问并压栈,确保不重复访问。

第 10 题

给定一个整数数组 nums,找到其中最长的严格上升子序列的长度。子序列是指从原数组中删除一些元素(或不删除)后,剩余元素保持原有顺序的序列。下面的程序横线处应该填入的是( )

cpp 复制代码
#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);

答案:D
解析: 最长上升子序列动态规划中,若 nums[i] > nums[j],则 dp[i] 可更新为 dp[j] + 1,取最大值。

第 11 题

给定一个整数数组 nums,找到其中最长的严格上升子序列的长度。子序列是指从原数组中删除一些元素(或不删除)后,剩余元素保持原有顺序的序列。该程序的时间复杂度为( )

cpp 复制代码
#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]) {
                dp[i] = max(dp[i], dp[j] + 1);
            }
        }
    }
    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(n 2 ^2 2)

B. O(n)

C. O(log⁡(n))

D. O(nlog⁡(n))

答案:A
解析: 双重循环遍历所有 ij,时间复杂度为 O(n 2 ^2 2)。

第 12 题

给定两个无向图 G1,G2,判断它们是否同构。图的同构是指两个图的节点可以通过某种重新编号的方式完全匹配,且边的连接关系一致。为了简化问题,假设图的节点编号从 0 到 n−1,并且图的边以邻接表的形式给出。下面程序中横线处应该给出的是( )。

cpp 复制代码
#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++) {
        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++) {
        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);

答案:C
解析: 为了生成每个节点的哈希串,需要将邻居编号转为字符串并用分隔符区分,避免歧义。

第 13 题

给定一个 m×n的二维网格 grid,每个格子中有一个非负整数。请找出一条从左上角 (0,0) 到右下角 (m−1,n−1)的路径,使得路径上的数字总和最小。每次只能向右或向下移动。横线处应该填入的是( )

cpp 复制代码
#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];

答案:B
解析: 最小路径和的状态转移方程为 dp[i][j] = min(dp[i-1][j], dp[i][j-1]) + grid[i][j]

第 14 题

给定一个整数数组 nums,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。下面横线处应该填入的是( )

cpp 复制代码
#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]);

答案:B
解析: 最大子数组和的状态转移方程为 dp[i] = max(nums[i], dp[i-1] + nums[i])

第 15 题

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

A. 链地址法(Chaining)

B. 开放地址法(Open Addressing)

C. 二次哈希法(Double Hashing)

D. 二分查找法(Binary Search)

答案:D
解析: 二分查找法是一种查找算法,不是哈希冲突解决策略。

第 16 题

在 C++ 语法中,表达式 1e6100000010^6 的值是相同的。

A. 正确

B. 错误

答案:B(错误)
解析: 1e6 是浮点数1000000,1000000 是整数,而 10^6 是异或运算,结果为12。

第 17 题

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

A. 正确

B. 错误

答案:A(正确)
解析: 编译器在调用函数前需要知道其原型,否则报错。

第 18 题

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

A. 正确

B. 错误

答案:A(正确)
解析: 快速排序的划分过程可能改变相等元素的相对顺序,因此不稳定。

第 19 题

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

A. 正确

B. 错误

答案:B(错误)
解析: double 有效位数约15-16位十进制,无法精确表示所有64位整数,如大于2^53的数。

第 20 题

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

A. 正确

B. 错误

答案:B(错误)
解析: cos 的参数是弧度,60弧度不是60度,结果不是0.5。

第 21 题

一颗 N层的满二叉树,一定有 2 N ^N N−1个结点。

A. 正确

B. 错误

答案:A(正确)
解析: 满二叉树节点数公式,若根为第1层,则N层共有2^N-1个节点。

第 22 题

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

A. 正确

B. 错误

答案:A(正确)
解析: 可以同时使用两种结构以优化不同操作,如快速查边用矩阵,遍历邻居用表。

第 23 题

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

A. 正确

B. 错误

答案:B(错误)
解析: 私有成员在子类中不可直接访问,虽然它们存在于对象中但不可见。

第 24 题

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

A. 正确

B. 错误

答案:A(正确)
解析: 递归可能导致栈溢出,对于大规模问题,递推更安全,因此有些问题实际只能用递推。

第 25 题

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

A. 正确

B. 错误

答案:B(错误)
解析: 考虑到实际家谱中可能存在近亲结婚导致祖先重复,从而破坏树的结构

完整GESP C++考级真题题解专栏:

GESP(C++ 一级+二级+三级)真题题解(持续更新):https://blog.csdn.net/weixin_66461496/category_12858102.html 点击跳转

GESP(C++ 四级+五级+六级)真题题解(持续更新):https://blog.csdn.net/weixin_66461496/category_12869848.html 点击跳转

GESP(C++ 七级+八级)真题题解(持续更新):
https://blog.csdn.net/weixin_66461496/category_13117178.html

更多csp信奥赛C++学习资料汇总:

1、csp/信奥赛C++,完整信奥赛系列课程(永久学习):

https://edu.csdn.net/lecturer/7901 点击跳转


2、CSP信奥赛C++竞赛拿奖视频课:

https://edu.csdn.net/course/detail/40437 点击跳转

3、csp信奥赛高频考点知识详解及案例实践:

CSP信奥赛C++动态规划:
https://blog.csdn.net/weixin_66461496/category_13096895.html点击跳转

CSP信奥赛C++标准模板库STL:
https://blog.csdn.net/weixin_66461496/category_13108077.html 点击跳转

信奥赛C++提高组csp-s知识详解及案例实践:
https://blog.csdn.net/weixin_66461496/category_13113932.html

4、csp信奥赛冲刺一等奖有效刷题题解:

CSP信奥赛C++初赛及复赛高频考点真题解析(持续更新):https://blog.csdn.net/weixin_66461496/category_12808781.html 点击跳转

信奥赛C++提高组csp-s初赛&复赛真题题解(持续更新)
https://blog.csdn.net/weixin_66461496/category_13125089.html

· 文末祝福 ·

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
int main(){
	cout<<"跟着王老师一起学习信奥赛C++";
	cout<<"    成就更好的自己!       ";
	cout<<"  csp信奥赛一等奖属于你!   ";
	return 0;
}
相关推荐
sycmancia2 小时前
C++——多态
开发语言·c++
像污秽一样3 小时前
算法设计与分析-算法效率分析基础-习题1.1
c语言·数据结构·c++·算法
2401_8846022712 小时前
程序人生-Hello’s P2P
c语言·c++
初中就开始混世的大魔王12 小时前
2 Fast DDS Library概述
c++·中间件·信息与通信
娇娇yyyyyy12 小时前
C++基础(6):extern解决重定义问题
c++
Neteen13 小时前
【数据结构-思维导图】第二章:线性表
数据结构·c++·算法
灰色小旋风14 小时前
力扣——第7题(C++)
c++·算法·leetcode
Ralph_Y14 小时前
C++网络:一
开发语言·网络·c++
程序猿编码14 小时前
探秘 SSL/TLS 服务密码套件检测:原理、实现与核心设计(C/C++代码实现)
c语言·网络·c++·ssl·密码套件