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

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


单选题

第1题

面向对象的编程思想主要包括( )原则。

A. 贪心、动态规划、回溯

B. 并发、并行、异步

C. 递归、循环、分治

D. 封装、继承、多态

【答案】:D

【解析】

A选项属于算法范畴。B选项涉及计算机系统和操作系统领域,不是面向对象编程的核心原则。C选项也属于语法和算法范畴。D选项是面向对象编程的三大基本原则。

第2题

运行下列代码,屏幕上输出( )。

#include <iostream>
using namespace std;

class my_class {
	public:
		static int count;
		my_class() {
			count++;
		}
		~my_class() {
			count--;
		}
		static void print_count() {
			cout << count << " ";
		}
};
int my_class::count = 0;
int main() {
	my_class obj1;
	my_class::print_count();
	my_class obj2;
	obj2.print_count();
	my_class obj3;
	obj3.print_count();
	return 0;
}

A. 1 1 1

B. 1 2 3

C. 1 1 2

D. 1 2 2

【答案】:B

【解析】

程序的主要逻辑:

  1. my_class类中有一个静态成员变量count,用于计数。
  2. 每创建一个my_class对象时,构造函数会将count加1;每销毁一个对象时,析构函数会将count减1。
  3. 静态方法print_count()用于输出当前的count值。

执行流程及输出分析

  • 在main函数开始前,my_class::count被初始化为0。
  • 创建第一个对象obj1:count变为1。
  • 调用print_count() :输出1。
  • 创建第二个对象obj2:count变为2。
  • 调用print_count() :输出2。
  • 创建第三个对象obj3:count变为3。
  • 调用print_count() :输出3。

因此,这段代码的输出结果是:123。

第3题

运行下列代码,屏幕上输出( )。

#include <iostream>
using namespace std;

class shape {
protected:
	int width, height;
public:
	shape (int a = 0, int b = 0) {
		width = a;
		height = b;
	}
	virtual int area() {
		cout << "parent class area: " << endl;
		return 0;
	}
};

class rectangle: public shape {
public:
	rectangle(int a = 0, int b = 0) : shape(a, b) { }

	int area () {
		cout << "rectangle area: ";
		return (width * height);
	}
};

class triangle: public shape {
public:
	triangle(int a = 0, int b = 0) : shape(a, b) { }

	int area () {
		cout << "triangle area: ";
		return (width * height / 2);
	}
};

int main() {
	shape *pshape;
	rectangle rec(10, 7);
	triangle tri(10, 5);

	pshape = &rec;
	pshape->area();

	pshape = &tri;
	pshape->area();
	return 0;
}

A. rectangle area: triangle area:

B. parent class area: parent class area:

C. 运行时报错

D. 编译时报错

【答案】:A

【解析】

执行流程及输出分析:

  1. 定义并初始化对象

    • 定义了一个指向shape类型的指针pshape。
    • 创建了两个具体的形状对象:矩形rec(10, 7)和三角形tri(10, 5)。
  2. 第一次调用area()方法

    • 将pshape指向rec对象,并调用pshape->area()。

    • 因为area()是虚函数,所以会调用rectangle类中的area()方法。

      水电费水电费

      cout << "rectangle area: ";
      return (width * height);  // 返回70,但返回值未被使用
      
    • 输出:reactangle area:。

  3. 第二次调用area()方法

    • 将pshape指向tri对象,并调用pshape->area()。

    • 同样因为area()是虚函数,会调用triangle类中的area()方法。

      cout << "triangle area: ";
      return (width * height / 2);  // 返回25,但返回值未被使用
      
    • 输出:triangle area:。

综上所述,程序的输出结果是:rectangle area: triangle area:

第4题

向一个栈顶为hs的链式栈中插入一个指针为s的结点时,应执行( )。

A. hs->next = s;

B. s->next = hs, hs = s;

C. s->next = hs->next; hs->next = s;

D. s->next = hs; hs = hs->next;

【答案】:B

【解析】

在链式栈中,新的元素总是插入到链表的头部,也就是说,新节点将成为第一个节点,而之前的第一个节点将成为第二个节点。

A. hs->next = s;

这个选项仅仅是把hs的下一个节点设为s,并没有更新hs本身,s也没有成为新的栈顶,这样会导致链表结构不正确。

B. s->next = hs, hs = s;

该选项首先将s的next指向当前的头节点hs,然后再将hs更新为s。这样做实际上是在链表头部插入了新的节点s,符合要求。

C. s->next = hs->next; hs->next = s;

这个选项让新节点s插入到hs后面的第二个位置,不符合链式栈的特性。

D. s->next = hs; hs = hs->next;

这个选项让新节点s的next指向当前的hs,但随后又把hs更新为hs->next,所以最后hs并不是指向新节点s,逻辑上是不正确的。

第5题

在栈数据结构中,元素的添加和删除是按照什么原则进行的?

A. 先进先出

B. 先进后出

C. 最小值先出

D. 随机顺序

【答案】B

【解析】

栈是一种“先进后出”(或“后进先出)的数据结构,最新加入的元素会最先被移除

第6题

要实现将一个输入的十进制正整数转化为二进制表示,下面横线上应填入的代码为( )。

#include <iostream>
using namespace std;

stack<int> ten2bin(int n) {
	stack<int> st;
	int r, m;

	r = n % 2;
	m = n / 2;
	st.push(r);

	while (m != 1) {
		r = m % 2;
		st.push(r);
		m = m / 2;
	}
	st.push(m);
	return st;
}

int main() {
	int n;
	cin >> n;
	stack<int> bin;
	bin = ten2bin(n);
	while (!bin.empty()) {
		____  // 在此处填入代码
	}
	return 0;
}

A. cout << bin.top(); bin.top();

B. bin.pop(); cout << bin.top();

C. cout << bin.back(); bin.pop();

D. cout << bin.front(); bin.pop();

【答案】:A

【解析】

主函数读取输入的整数n,调用ten2bin函数将其转换为二进制,并将结果存储在bin栈中。然后,通过循环遍历该栈,输出其中的元素。

填空部分分析:

为了正确地输出二进制表示,需要从栈顶依次弹出元素并打印,因为栈是LIFO结构,而我们需要按顺序输出二进制位。

A. cout << bin.top(); bin.top();

这是正确的选择,因为它首先获取栈顶元素并输出,然后移除栈顶元素,从而实现正确的二进制输出。

B. bin.pop(); cout << bin.top();

这是错误的,因为它先移除了栈顶元素,再试图访问栈顶,这会使得第1位的值没有输出,从而导致结果错误。

C. cout << bin.back(); bin.pop();

这是错误的,因为stack容器没有back()方法。

D. cout << bin.front(); bin.pop();

这是错误的,因为stack容器没有front()方法。

因此,正确的代码应该是:A.cout << bin.top(); bin.top();

第7题

下面定义了一个循环队列的类,请补全判断队列是否满的函数,横向上应填写( )

#include <iostream>
using namespace std;

class circular_queue {
private:
	int *arr;  // 数组用于存储队列元素
	int capacity;  // 队列容量
	int front;  // 队头指针
	int rear;  // 队尾指针

public:
	circular_queue(int size) {
		capacity = size + 1;  // 为了避免队列满时与队列空时指针相等的情况,多预留一个空间
		arr = new int[capacity];
		front = 0;
		rear = 0;
	}

	~circular_queue() {
		delete[] arr;
	}

	bool is_empty() {
		return front == rear;
	}

	bool is_full() {
		____  // 在此处填入代码
	}

	void en_queue(int data) {
		if (is_full()) {
			cout << "队列已满,无法入队!" << endl;
			return -1;
		}
		arr[rear] = data;
		rear = (rear + 1) % capacity;
		return 1;
	}

	int de_queue() {
		if (is_empty()) {
			cout << "队列为空,无法出队!" << endl;
			return -1;  // 出队失败,返回一个特殊值
		}
		int data = arr[front];
		front = (front + 1) % capacity;
		return data;
	}
};

A. return (rear + 1) % capacity == front;

B. return rear % capacity == front;

C. return rear == front;

D. return (rear + 1) == front;

【答案】:A

【解析】

为了区分队列满和队列空状态,我们使用额外的一个空间。当(rear+1) % capacity == front时,说明队列已经满了。

第8题

对"classmycls"使用哈夫曼(Huffman)编码,最少需要( )比特。

A. 10

B. 20

C. 25

D. 30

【答案】:C

【解析】

字符串“classmycls”的字符频率:

  • c:2次
  • l:2次
  • a:1次
  • s:3次
  • m:1次
  • y:1次

构建哈夫曼树(根据字符的频率,从小到大排序,并依次合并节点)并生成编码(从根节点开始,左边路径标记为0,右边路径标记为1)

计算总比特数:

根据每个字符的频率乘以其编码长度,然后求和得到总比特数。

  • c:2 * 2 = 4 bits
  • l:2 * 2 = 4 bits
  • a:1 * 4 = 4 bits
  • s:3 * 2 = 6 bits
  • m:1 * 4 = 4 bits
  • y:1 * 3 = 3 bits

总比特数=4+4+4+6+4+3=25bits。因此,答案应该是C。

第9题

二叉树的( )第一个访问的节点是根节点。

A. 先序遍历

B. 中序遍历

C. 后序遍历

D. 以上都是

【答案】A

【解析】

先序遍历:按照“根-左-右”的顺序进行遍历。

第10题

一棵5层的满二叉树中节点数为( )。

A. 31

B. 32

C. 33

D. 16

【答案】:A

【解析】

满二叉树:在满二叉树中,所有非叶子节点都有两个子节点,并且所有叶子节点都在同一层。满二叉树的节点总数可以用公式来表示:。其中(N)是节点总数,(h)是树的高度(层数)。

对于一棵5层的满二叉树来说:节点总数=-1=31。

因此,正确答案是A。

第11题

在求解最优化问题时,动态规划常常涉及到两个重要性质,即最优子结构和( )。

A. 重叠子问题

B. 分治法

C. 贪心策略

D. 回溯算法

【答案】A

【解析】

动态规划的基本原理和它所依赖的两个关键性质:

  1. 重叠子问题:这是指将一个大问题分解成多个小问题,这些小问题会被多次重复计算。在动态规划中,通过存储这些小问题的结果,可以避免重复计算,从而提高效率。
  2. 最优子结构:这是指一个问题的最优解可以通过其子问题的最优解来构建,这意味着解决了子问题的最优解后,可以组合成原问题的最优解。

因此,正确答案是A。

第12题

青蛙每次能跳1或2步,下面代码计算青蛙跳到第n步台阶有多少种不同跳法。则下列说法,错误的是( )。

int jump_recur(int n) {
	if (n==1) return 1;
	if (n==2) return 2;
	return jump_recur(n-1) + jump_recur(n-2);
}

int jump_dp(int n) {
	vector<int> dp(n+1);  // 创建一个动态规划数组,用于保存已计算的值
	// 初始化前两个数
	dp[1] = 1;
	dp[2] = 2;
	// 从第三个数开始计算斐波那契数列
	for (int i=3; i<=n; ++i) {
		dp[i] = dp[i-1] + dp[i-2];
	}
	return dp[n];
}

A. 函数jump_recur()采用递归方式。

B. 函数jump_dp()采用动态规划方法。

C. 当n较大时,函数jump_recur()存在大量重复计算,执行效率低。

D. 函数jump_recur()代码量小,执行效率高。

【答案】:D

【解析】

A. 函数jump_recur()采用递归方式。

从代码中可以看到,jump_recur函数通过调用自身来解决子问题,这正是递归的定义。因此这个选项是正确的

B. 函数jump_dp()采用动态规划方法

jump_dp函数创建了一个数组dp来存储已经计算过的结果,并从底向上地填充该数组。这正是动态规划的典型实现方法。因此这个选项也是正确的

C. 当n较大时,函数jump_recur()存在大量重复计算,执行效率低。

由于jump_recur包每次都要重新计算之前的结果,当n较大时,会导致大量的重复计算,从而使得效率很低。因此这个选项也是正确的。

D. 函数jump_recur()代码量小,执行效率高。

虽然jump_recur的代码量确实较少,但它的执行效率并不高,尤其是在n较大的情况下会有大量的重复计算。因此这个选项是错误的。

综上所述,正确答案是D。

第13题

阅读以下二叉树的广度优先搜索代码:

#include <iostream>
#include <queue>
using namespace std;

// 二叉树节点的定义
struct TreeNode {
	int val;
	TreeNode* left;
	TreeNode* right;
	TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
};

// 宽度优先搜索(BFS)迭代实现
TreeNode* bfs(TreeNode* root, int a) {
	if (root==nullptr) return nullptr;
	queue<TreeNode*> q;
	q.push(root);
	while (!q.empty()) {
		TreeNode* node = q.front();
		q.pop();
		if (node->val == a)
			return node;
		cout << node->val << " ";  // 先访问当前节点
		if (node->left) q.push(node->left);  // 将左子节点入队
		if (node->right) q.push(node->right);  // 将右子节点入队
	}
	return nullptr;
}

使用以上算法,在以下这棵树搜索数值20时,可能的输出是( )。

image

A. 5 2 -4 3 17 9

B. -4 2 3 5 9 17

C. 5 2 17 -4 3 9

D. 以上都不对

【答案】:C

【解析】

bfs函数实际上对于二叉树进行层次遍历,在遍历的过程中来找值(val)为20的结点,由于没有该结点,所以会把整棵树遍历结束之后就返回nullptr。

因此,最终的输出就是层次遍历的结果:5 2 17 -4 3 9。

第14题

同上题中的二叉树,阅读以下二叉树的深度优先搜索代码:

#include <iostream>
#include <stack>
using namespace std;

// 非递归深度优先搜索(DFS)
TreeNode* dfs(TreeNode* root, int a) {
	if (root == nullptr) return nullptr;
	stack<TreeNode*> stk;
	stk.push(root);
	while (!stk.empty()) {
		TreeNode* node = stk.top();
		stk.pop();
		if (node->val == a)
			return node;
		cout << node->val << " ";  // 访问当前节点
		if (node->right) stk.push(node->right);  // 先压入右子节点
		if (node->left) stk.push(node->left);  // 再压入左子节点
	}
	return nullptr;
}

使用以上算法,在二叉树搜索数值20时,可能的输出是( )。

A. 5 2 -4 3 17 9

B. -4 2 3 5 9 17

C. 5 2 17 -4 3 9

D. 以上都不对

【答案】A

【解析】

dfs函数实际上对于二叉树进行先序遍历,在遍历的过程中来找值(ual)为20的结点,由于没有该结点,所以会把整棵树遍历结束之后就返回null ptr。

因此,最终的输出就是先序遍历的结果:5 2 -4 3 17 9。

第15题

在上题的树中搜索数值3时,采用深度优先搜索一共比较的节点数为( )。

A. 2

B. 3

C. 4

D. 5

【答案】C

【解析】

深度优先搜索过程:

  1. 从根节点5开始,将其加入栈。
  2. 弹出栈顶元素5,检查是否等于目标值3。不是,于是将5的右子节点17和左子节点2压入栈。
  3. 弹出栈顶元素2,检查是否等于目标值3。不是,于是将2的右子节点3和左子节点-4压入栈。
  4. 弹出栈顶元素-4,检查是否等于目标值3。不是,继续。
  5. 弹出栈顶元素3,检查是否等于目标值3。是,找到目标节点。

根据上述步骤,共访问了四个节点:5,2,-4,3,需要比较的节点数是4个。所以正确答案是C。

判断题

第1题

哈夫曼编码本质上是一种贪心策略。

A. 正确

B. 错误

【答案】:A

【解析】

哈夫曼编码(Huffman coding)是一种用于数据压缩的算法,确实基于贪心策略来构建最优前缀码。

第2题

创建一个对象时,会自动调用该对象所属类的构造函数。如果没有定义构造函数,编译器会自动生成一个默认的构造函数。

A. 正确

B. 错误

【答案】:A

【解析】

在C++中,如果没有定义任何构造函数,编译器会提供一个隐式的默认构造函数。

第3题

定义一个类时,必须手动定义一个析构函数,用于释放对象所占用的资源。

A. 正确

B. 错误

【答案】:B

【解析】

在C++中,如果不定义析构函数,编译器会生成一个默认的析构函数,但如果类管理动态内存或其他资源,通常需要自定义析构函数以确保资源被正确释放。

第4题

C++中类内部可以嵌套定义类。

A. 正确

B. 错误

【答案】:A

【解析】

在C++中,可以在一个类的内部定义另一个类,这称为嵌套类。

第5题

000, 001, 011, 010, 110, 111, 101, 100是一组格雷码。

A. 正确

B. 错误

【答案】:A

【解析】

格雷码是一种二进制数系,其中相邻两个数只有一位不同。这组数字确实符合格雷码的定义。

第6题

n个节点的双向循环链表,在其中查找某个节点的平均时间复杂度是O(logn)。

A. 正确

B. 错误

【答案】:B

【解析】

对于链表结构,无论是单向还是双向,其查找操作的平均时间复杂度都是O(n)而不是O(logn)。

第7题

完全二叉树可以用数组存储数据。

A. 正确

B. 错误

【答案】:A

【解析】

完全二叉树可以非常方便地用数组来存储数据。对于一个节点在数组中的位置(i)(假设从1开始计数),其子节点和父节点的位置可以通过以下公式计算:

  1. 左孩子节点的位置:2i
  2. 右孩子节点的位置:2i+1
  3. 父节点的位置:

这种方式利用了完全二叉树的性质,即除了最后一层外,每一层都是满的,并且最后一层的所有节点尽可能靠左排列。

第8题

在C++中,静态成员函数只能访问静态成员变量。

A. 正确

B. 错误

【答案】:A

【解析】

静态成员函数不能访问非静态成员变量,因为它们属于类本身,而不是某个具体的对象实例。

第9题

在深度优先搜索中,通常使用队列来辅助实现。

A. 正确

B. 错误

【答案】:A

【解析】

深度优先搜索(DFS)通常使用栈来实现,而广度优先搜索(BFS)才使用队列。

第10题

对0-1背包问题,贪心算法一定能获得最优解。

A. 正确

B. 错误

【答案】:A

【解析】

0-1背包问题是NP完全问题,贪心算法不能保证求得最优解,通常需要使用动态规划或搜索等方法。

编程题

题解:洛谷 P10721 [GESP202406 六级] 计算得分

题解:洛谷 P10722 [GESP202406 六级] 二叉树

posted @ 2026-07-17 15:28  团爸讲算法  阅读(4)  评论(0)    收藏  举报