GESP认证C++编程真题解析 | 202603 六级

​欢迎大家订阅我的专栏:算法题解:C++与Python实现
本专栏旨在帮助大家从基础到进阶 ,逐步提升编程能力,助力信息学竞赛备战!

专栏特色
1.经典算法练习:根据信息学竞赛大纲,精心挑选经典算法题目,提供清晰的代码实现与详细指导,帮助您夯实算法基础。
2.系统化学习路径:按照算法类别和难度分级,从基础到进阶,循序渐进,帮助您全面提升编程能力与算法思维。

适合人群:

  • 准备参加蓝桥杯、GESP、CSP-J、CSP-S等信息学竞赛的学生
  • 希望系统学习C++/Python编程的初学者
  • 想要提升算法与编程能力的编程爱好者

附上汇总帖:GESP认证C++编程真题解析 | 汇总


单选题

第1题

下列关于 C++ 中类的描述,正确的是( )。

A. 如果类没有用户声明的构造函数,那么编译器会隐式声明一个默认构造函数

B. 类的析构函数可以被重载,一个类可以有多个析构函数

C. 类中的所有成员都必须声明为 public

D. 类和结构体在 C++ 中没有区别,包括默认访问权限也相同

【答案】:A

【解析】

编译器在用户未声明构造函数时,会隐式声明默认构造函数,A正确。

析构函数不可重载,一个类只能有一个析构函数,B错误。

类成员的访问权限可声明为publicprotectedprivate,C错误。

class默认为private,而struct默认为public,D错误。

第2题

下列代码中, s1->draw();s2->draw(); 输出不同结果的主要原因是( )。

class Shape {
public:
	virtual void draw() {
		cout << "绘制图形" << endl;
	}

	virtual ~Shape() {}
};

class Circle : public Shape {
public:
	void draw() override {
		cout << "绘制圆形" << endl;
	}
};

class Rectangle : public Shape {
public:
	void draw() override {
		cout << "绘制矩形" << endl;
	}
};

int main() {
	Shape* s1 = new Circle();
	Shape* s2 = new Rectangle();

	s1->draw();
	s2->draw();

	delete s1;
	delete s2;
	return 0;
}

A. draw() 是普通成员函数

B. Shape 中的 draw() 被声明为虚函数

C. CircleRectangle 中使用了 public 继承

D. 指针变量名不同

【答案】:B

【解析】

C++通过虚函数实现多态,即当基类指针指向不同派生类对象时,调用同一函数会自动执行对应类的具体实现。这种机制让程序能在运行时根据对象的实际类型,动态决定调用哪个版本的函数。

第3题

下面的代码在 main() 中有一行会导致编译错误,请找出来。

class Pet {
public:
	Pet(string n, int a) : name(n), age(a) {}
	string getName() { return name; }
	void birthday() { age++; }
private:
	string name;
	int age;
};

int main() {
	Pet cat("奶茶", 2);
	cout << cat.getName(); // ①
	cat.birthday(); // ②
	cat.name = "大橘"; // ③
	cout << cat.getName(); // ④
}

A. 第 ① 行

B. 第 ② 行

C. 第 ③ 行

D. 第 ④ 行

【答案】:C

【解析】

题目中name是私有成员,不能在类的外部直接通过cat.name进行访问和修改。

第4题

游乐园的过山车每次限坐 4 人,用循环队列管理排队(容量 MAX=5 ,空一格判满)。下面代码执行后,循环队列是否已满? rear 的值是多少?

const int MAX = 5;
int queue[MAX];
int front = 0, rear = 0;

// 入队
void enqueue(int x) {
	queue[rear] = x;
	rear = (rear + 1) % MAX;
}
// 出队
void dequeue() {
	front = (front + 1) % MAX;
}
int main() {
	enqueue(1); enqueue(2); enqueue(3); enqueue(4);
	dequeue(); dequeue();
	enqueue(5); enqueue(6);
}

A. 已满, rear = 1

B. 未满, rear = 1

C. 已满, rear = 2

D. 未满, rear = 4

【答案】:A

【解析】

模拟操作后,此时队列中包含4个元素,已达满载状态,rear值为1。

第5题

在以下计算机系统应用场景中,最适合使用循环队列的是( )。

A. 函数调用过程中,保存局部变量和返回地址

B. 表达式求值中的运算符优先级处理

C. 操作系统中的进程优先级调度(高优先级先执行)

D. 生产者和消费者问题中的共享缓冲区

【答案】:D

【解析】

函数调用和表达式优先级计算是栈的典型应用场景,A、B错误。

操作系统中的优先级调度直观来看适合基于优先队列(堆)实现,实际比较常见的是用多个队列实现,C错误。

生产者与消费者模型在利用缓冲区时,则通过队列来实现,D正确。

第6题

在二叉搜索树(BST)中,若中序遍历的序列为{1, 2, 3, 4, 5},且先序遍历的第一个序列元素为3,则下列说法正确的是( )。

A. 该树一定是一棵完全二叉树。

B. 元素4和5不可能是兄弟节点。

C. 元素1所在节点的深度可能大于3(根节点深度为1)。

D. 元素2一定是元素1的父节点。

【答案】:B

【解析】

由先序遍历首元素可知根节点为3,结合二叉搜索数的“左小右大”性质,以及中序遍历序列。将树划分为含结点1、2的左子树和含结点4、5的右子树,A错误。

右子树只含4和5两个结点,必然是父子层级关系,B错误。

左子树仅含1和2两个结点,最大深度为3,C错误。

1可能是2的父节点,2也可能是1的父节点,D错误。

第7题

某二叉树共有10个结点,记为A~J,已知它的先序遍历序列为:A B D H I E C F J G,中序遍历序列为:H D I B E A F J C G,则该二叉树的后序遍历序列是( )。

A. H I D E B J F G C A

B. H I D B E J F G C A

C. I H D E B J F G C A

D. H I D E B F J G C A

【答案】:A

【解析】

根据口诀“先后定根,中分左右”来构建,选A

第8题

下列关于树的遍历的说法中,正确的一项是( )。

A. 对任意一棵树进行深度优先遍历,所得序列一定唯一。

B. 已知一棵二叉树的先序遍历和后序遍历序列,可以唯一确定这棵二叉树。

C. 已知一棵二叉树的先序遍历和中序遍历序列,可以唯一确定这棵二叉树。

D. 已知一棵二叉树的先序遍历序列,可以唯一确定这棵二叉树。

【答案】:C

【解析】

对于普通树(多叉树),由于其子节点之间没有固定的左右顺序,深度优先遍历时的访问次序可以任意选择,因此生成的遍历序列可能不唯一,A错误。

先序遍历和中序遍历可以唯一确定一颗二叉树,是因为二叉树严格区分左右子树,中序序列能明确划分根结点的左右集合,配合先序序列确定的根节点即可递归构建出唯一结构,C正确。

第9题

6 个字符,它们出现的次数分别为: {2, 3, 3, 4, 6, 8} ,现在用哈夫曼编码为这些字符编码,最小加权路径长度WPL(每个字符的出现次数 × \times × 它的编码长度,再把每个字符结果加起来)的值为( )。

A. 58

B. 60

C. 62

D. 64

【答案】:D

【解析】

带全路径长度(WPL)定义为各字符的编码长度与其权值(出现次数)乘积之和。

具体计算步骤如下:

  1. 编码长度为3,对应权值2和3:贡献为 3 * (2 + 3) = 15
  2. 编码长度为3,对应权值3和4:贡献为 3 * (3 + 4) = 21
  3. 编码长度为2,对应权值6和8:贡献为 2 * (6 + 8) = 28

最终求和:15 + 21 + 28 = 64

第10题

n n n 个不同符号的符号进行哈夫曼编码。若生成的哈夫曼树共有 115 115 115 个结点,则 n n n 的值是( )。

A. 60

B. 58

C. 57

D. 56

【答案】:B

【解析】

哈夫曼编码,每进行一次合并操作,独立的结点集合数量减少1个,n节点最终合并成为1个结点会合并n-1次。故叶子结点为n时,总节点数为2*n-1。

第11题

关于格雷编码(Gray Code),下列说法正确的是( )。

A. 格雷编码中,编码位数越多,相邻编码之间变化的位数也越多

B. 格雷编码中,相邻两个编码的二进制位恰好有一位不同

C. 格雷编码就是把普通二进制编码按位取反后得到的结果

D. 格雷编码不能用于数字电路和状态转换的设计中

【答案】:B

【解析】

格雷码任意两个相邻的编码(包括首尾两个编码),在二进制表示上恰好只有一位不同。

第12题

给定一棵二叉树,采用广度优先搜索 (BFS) 算法,返回右视图所有节点的值。其中右视图定义为:二叉树的右视图是从树的右侧看过去时可见的节点集合,即右视图中的每个节点都是某一层中最右侧的节点。

struct TreeNode {
	int val;
	TreeNode* left;
	TreeNode* right;
	TreeNode(int x): val(x), left(nullptr), right(nullptr) {}
};

vector<int> rightSideView(TreeNode* root) {
	unordered_map<int, int> rightmostValueAtDepth;
	int max_depth = -1;

	queue<TreeNode*> nodeQueue;
	queue<int> depthQueue;
	nodeQueue.push(root);
	depthQueue.push(0);

	while (!nodeQueue.empty()) {
		TreeNode* node = nodeQueue.front(); nodeQueue.pop();
		int depth = depthQueue.front(); depthQueue.pop();

		if (node != NULL) {
			max_depth = max(max_depth, depth);

			rightmostValueAtDepth[depth] = node->val;

			nodeQueue.push(node->left);
			nodeQueue.push(node->right);

			depthQueue.push(________);
			depthQueue.push(________);
		}
	}

	vector<int> rightView;
	for (int depth = 0; ________; ++depth) {
		rightView.push_back(rightmostValueAtDepth[depth]);
	}
	return rightView;
};

A.

depth
depth
depth < max_depth

B.

depth + 1
depth + 1
depth <= max_depth

C.

depth + 1
depth + 1
depth < max_depth

D.

depth
depth
depth <= max_depth

【答案】:B

【解析】

子节点深度 = 父节点深度 + 1。

max_depth是depth的最大值,访问时应该是depth<=max_depth。

第13题

下列关于树的深度优先搜索(DFS)的说法中,正确的是( )。

A. 对树进行 DFS 时,一定是按层从上到下依次访问结点

B. 对任意一棵树进行 DFS,得到的遍历序列唯一

C. 对一棵树进行 DFS 时,常借助递归或栈实现

D. DFS 只能用于二叉树,不能用于普通树

【答案】:C

【解析】

对二叉树进行DFS遍历,主要通过递归或栈来实现。

第14题

小朋友们去邻里拜年,每个家里有不同数量的糖果。规则是:不能连续进入两个相邻的房子(即不能同时 取相邻两家的糖果)。目标是拿到最多糖果。以下是代码实现,请补全横线。

int visit(vector<int>& nums) {
	if (nums.empty()) {
		return 0;
	}
	int size = nums.size();
	if (size == 1) {
		return nums[0];
	}
	vector<int> dp = vector<int>(size, 0);
	dp[0] = nums[0];
	dp[1] = max(nums[0], nums[1]);

	for (int i = 2; i < size; i++) {
		dp[i] = ______; // 在此处填写代码
	}

	return dp[size - 1];
}

A. dp[i] = dp[i - 1] + nums[i];

B. dp[i] = max(dp[i - 1], dp[i - 2] * nums[i]);

C. dp[i] = max(dp[i - 1], dp[i - 2] + nums[i]);

D. dp[i] = dp[i - 2] + nums[i];

【答案】:C

【解析】

状态定义:dp[i] 表示考虑前 i 个房子时,能获取糖果的最大数量

状态转移方程:dp[i] = max(dp[i-1], dp[i-2] + nums[i],不取第 i 个房子,结果为 dp[i-1]。取第 i 个房子,结果为 dp[i-2] + nums[i],这意味着跳过第 i-1 个房子,直接在前 i-2 个房子的最优解基础上加上第 i 个房子的糖果数。最终取这两种情况的最大值。

第15题

元宵节晚上,小朋友沿着一条发光石板路前进,每次可向前走 1 块或 2 块石板。动态规划定义如下:dp[i] = dp[i - 1] + dp[i - 2] ,下面关于 dp[i] 的含义最合适的是( )。

A. 走到第 i 块石板的不同走法数量

B. 走到第 i 块石板时,已经走过的石板总数

C. 从第 i 块石板走回起点的最少步数

D. 从第 i 块石板走回起点的最大步数

【答案】:A

【解析】

dp[i] 表示走到第 i 块石板的不同走法的数量。

判断题

第1题

下面定义了一个表示二维坐标点的类 Point , 并提供了一个带参数的构造函数,但第 ② 行 Point b; 会调用编译器自动生成的默认构造函数,将 b.xb.y 被初始化为 0.0,程序可以正常编译运行。

class Point {
public:
	double x, y;
	Point(double px, double py) : x(px), y(py) {}
	void print() {
		cout << "(" << x << ", " << y << ")";
	}
};

int main() {
	Point a(3.0, 4.0); // ①
	Point b; // ②
	a.print();
}

A. 正确

B. 错误

【答案】:B

【解析】

只有当类中未定义任何构造函数时,编译器才会隐式生成默认构造函数。一旦代码中显式定义了构造函数(无论是有参还是无参),编译器将不再生成默认的无参构造函数。

第2题

C++ 中的继承支持单继承和多继承,但子类无法直接访问父类的私有成员。

A. 正确

B. 错误

【答案】:A

【解析】

子类无法直接访问父类的私有变量。

第3题

对如下结构的树,执行 travel 函数,输出结果是 1 2 3 4 5

       1
      / \
     2   3
    / \
   4   5
struct Node {
	int val;
	Node *left, *right;
	Node(int v) : val(v), left(nullptr), right(nullptr) {}
};

void travel(Node* root) {
	if (!root) return;
	stack<Node*> s;
	s.push(root);

	while (!s.empty()) {
		Node* cur = s.top(); s.pop();
		cout << cur->val << " ";

		if (cur->right) s.push(cur->right);
		if (cur->left) s.push(cur->left);
	}
}

A. 正确

B. 错误

【答案】:B

【解析】

子节点入栈是先右后左。1入栈后出栈;接着3、2入栈,随后2出栈;然后5、4入栈,最后4、5依次出栈。

出栈的顺序是:1、2、4、5、3。

第4题

若所有字符出现频率相同,则哈夫曼编码一定会得到完全二叉树。

A. 正确

B. 错误

【答案】:B

【解析】

哈夫曼树构建的时候,没有要求必须叶子结点从左到右构建,所以最后一层叶子结点完全可能靠后。

第5题

哈夫曼编码是一种变长的前缀编码,在解码时不需要额外的分隔符就能唯一还原,这是因为在哈夫曼树中,任何一个字符的叶子结点都不会成为另一个字符结点的祖先。

A. 正确

B. 错误

【答案】:A

【解析】

哈夫曼编码是前缀变长编码。

第6题

在 C++ 中使用一维数组 vector<int> tree 存储按层序遍历的完全二叉树时,若根节点存储在 tree[0] ,则对于任意非空节点 tree[i] ,其右孩子(如果存在)必然位于 tree[2 * i + 2]

A. 正确

B. 错误

【答案】:A

【解析】

当结点编号从1开始时,若当前结点为 i,则其左孩子为 2i,右孩子为 2i+1;若结点编号从0开始,则左孩子为 2i+1,右孩子为 2i+2。

第7题

在 C++ 中使用栈来非递归地实现二叉树的前序遍历时,为了保证遍历顺序正确,在处理完当前结点后,应该先将该结点的左孩子压入栈中,然后再将右孩子压入栈中。

A. 正确

B. 错误

【答案】:B

【解析】

使用栈实现先序遍历时,应先将右子节点入栈,再将左子节点入栈,从而确保左子节点能够被优先弹出并访问。

第8题

设二叉树共有 n n n 个结点,函数 preorderTraversal 以下代码的时间复杂度为 O ( n ) O(n) O(n),空间复杂度为 O ( n ) O(n) O(n)

struct TreeNode {
	int val;
	TreeNode* left;
	TreeNode* right;
	TreeNode(int x): val(x), left(nullptr), right(nullptr) {}
};

void preorder(TreeNode *root, vector<int> &res) {
	if (root == nullptr) {
		return;
	}
	res.push_back(root->val);
	preorder(root->left, res);
	preorder(root->right, res);
}

vector<int> preorderTraversal(TreeNode *root) {
	vector<int> res;
	preorder(root, res);
	return res;
};

A. 正确

B. 错误

【答案】:A

【解析】

前序遍历将每个结点按顺序存入vector中,其时间复杂度和空间复杂度均为 O ( n ) O(n) O(n)

第9题

下列代码实现了一个0-1背包的一维动态规划代码,内层循环是经典的逆序写法。若将内层循环改成正序遍 历(即 for (int j = w[i]; j <= W; j++) ),仍能得到正确答案。

int main() {
	int W = 5;
	int w[] = {2, 3, 4};
	int v[] = {10, 1, 1};
	int n = 3;
	int dp[6] = {0};

	for (int i = 0; i < n; i++) {
		for (int j = W; j >= w[i]; j--) { // ← 逆序!
			dp[j] = max(dp[j], dp[j - w[i]] + v[i]);
		}
	}
	cout << dp[W];
}

A. 正确

B. 错误

【答案】:B

【解析】

若内层循环采用正序遍历,可能会导致同一物品被重复计算多次(完全背包的写法)。

第10题

在动态规划问题中,状态空间相同且没有重复计算的情况下,“状态转移方程+递推”与“递归+记忆化搜索”的时间复杂度通常相同。

A. 正确

B. 错误

【答案】:A

【解析】

两者只是表达形式不同,时间复杂度通常相同。

编程题

题解:洛谷 P15800 [GESP202603 六级] 选数

题解:洛谷 P15801 [GESP202603 六级] 完全二叉树

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值