CCF编程能力等级认证GESP—C++6级—样题1

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

1、以下不属于计算机输出设备的有( )。

A.麦克风
B.音箱
C.打印机
D.显示器

2、小明想了一个 1 到 100 之间的整数。你可以做多次猜测,每次猜测之后,如果你没有猜中,小明会告诉你,你猜的数比他想的数大还是小。你希望你在运气最坏的情况下花费最少的次数猜中,请问你运气最坏的情况下会猜几次?(包括最后猜中的那次)

A.6
B.7
C.8
D.100

3、关于分治算法,下列说法错误的是( )。

A.分治算法的核心思想是分而治之,即把问题转化为多个规模更小的子问题求解。
B.分治算法可以不使用递归实现。
C.分治算法的时间复杂度是𝑂(log 𝑁),其中𝑁表示问题的规模。
D.二分法、快速排序等算法都是典型的使用分治思想的算法。

4、下面关于 C++类的说法中,正确的是( )。

A.派生类不能和基类有同名成员函数,因为会产生歧义。
B.派生类可以和基类有同名成员函数,派生类覆盖基类的同名成员函数。
C.派生类可以和基类有同名成员函数,但是否覆盖同名成员函数需要取决于函数参数是否一致。
D.C++中派生类不继承基类的任何成员函数。

5、关于下面 C++代码说法错误的是( )。

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

class Pet{
public:
	string kind;
	int age;
	Pet(string _kind, int _age):kind(_kind), age(_age){}
};
class Dog : public Pet{
public:
	string color;
	Dog(string _kind, int _age, string _color):Pet(_kind, age), color(_color){} 
};
int main(){
	auto dog = Dog("dog", 3, "white");
	cout << "kind: " << dog.kind << endl;
	cout << "age: " << dog.age << endl;
	cout << "color: " << dog.color << endl;
	return 0;
}
A.Pet 类是基类,Dog 类是子类。
B.Dog 类的构造函数中,将自动调用 Pet 类的构造函数。
C.dog 是 Dog 类的实例。
D.最后一行(即输出行 A)输出代码会报错,因为 Pet 类中没有成员变量color

6、以下几个类定义中不能顺利通过编译的是( )。

class A{
public:
	void func(int a, int b, int c){};
};

class B{
public:
	void func(int a, int b = 1, int c = 1){};
};

class C{
public:
	void func(int a = 3, int b, int c){};
};

class D{
public:
	void func(int a = 3, int b = 1, int c = 0){};
};
A.class A
B.class B
C.class C
D.class D

7、 关于运算符重载,下列说法正确的是( )。

A.对于下列代码中的两个运算符重载实现:虽然它们的参数类型都是 int 与Test 的组合,这段代码仍可以通过编译。
这是因为在两个重载实现中,int与 Test 在参数中的顺序不同,编译器能够唯一地确定调用哪个运算符实现代码。

#include <iostream>

using namespace std;

class Test{
public:
	int data;
	Test(int d):data(d){}
};
Test operator +(const Test& a, const int& b){
	return Test(a.data + b);
}
Test operator +(const int& b, const Test& a){
	return Test(- a.data - b);
}
int main(){
	Test obj(1);
	int data = 2;
	cout << (obj + data).data << endl;
	cout << (data + obj).data << endl;
	return 0;
}

B.A 的说法是错误的。这是因为加法满足交换律,因此即便调换 A 和 int 的顺序,加法运算的实现仍必须保持一致,
编译器在编译时也会检查这一点。如将后一处 int 改为 double,则可通过编译。
C.A 和 B 的说法都是错误的。运算符重载时,所有参数以及返回值的类型必须完全相同。
因此,即便是下列代码中的运算符重载实现,也不能通过编译。

class Test{
public:
	int data;
	Test(int d):data(d){}
};
Test operator +(const Test& a, const int& b){
	return Test(a.data + b);
}

D.A、B、C 的说法都是错误的。

8、关于 C++程序的异常处理,以下选项中描述错误的是( )。

A.编程语言中的异常和错误是不同的概念。
B.异常一旦发生,程序便一定不能继续执行。
C.通过 trycatch 等保留字提供异常处理功能。
D.程序使用 throw 在任何地方抛出各种异常。

9、有关下面 C++代码的说法,正确的是( )。

#include <iostream>
#include <cassert>
using namespace std;
class MoreData{
	int* __data;
	int head, tail, capacity;
public:
	MoreData(int cap){
		capacity = cap;
		__data = new int[capacity];
		head = tail = 0;
	}
	MoreData& push(int val){
		assert(tail < capacity);
		__data[tail++] = val;
		return *this;
	}
	int pop(){
		assert(head < tail);
		return __data[--tail];
	}
	int size(){
		return tail - head;
	}
};
int main(){
	auto myData = MoreData(100);
	myData.push(4).push(5);
	cout << myData.pop() << endl;
	cout << myData.pop() << endl;
	cout << myData.pop() << endl;
	return 0;
}
A.moreData 类可用于构造队列(queue)数据结构。
B.myData.push(4).push(5);的连续 push()用法将导致错误。
C.前两个 cout << myData.pop() << endl;代码可以正确运行,分别输出 45。
D.最后一个 cout << myData.pop() << endl;代码可以通过编译,但不能正常运行,因为 pop 函数中的断言 assert(head < tail);会失败。

10、如下图所示的哈夫曼树,按照哈夫曼编码规则,假设图中字符 C 的编码为0,则 E 的编码为( )。
在这里插入图片描述

A.1111
B.1010
C.1101
D.1001

11、 下面有关格雷码的说法,错误的是( )。

A.格雷码是无权码。
B.格雷码是循环码。
C.011100 是一组相邻的格雷码。
D.格雷码相邻的码组间仅有一位不同。

12、在具有2𝑁个结点的完全二叉树中,叶子结点个数为( )。

A. 𝑁/2
B. 𝑁 − 1
C. 𝑁
D. 𝑁 + 1

13、有关下图的二叉树,说法正确的有( )个。
在这里插入图片描述

A.0
B.1
C.2
D.3

14、 现希望存储整数𝑁的所有质因子,请问其空间复杂度上界为是( )。

A. O ( l o g l o g N ) O(log log N) O(loglogN)
B. O ( l o g N ) O(log N) O(logN)
C. O ( N ) O(\sqrt{N}) O(N )
D. O ( N ) O(N) O(N)

15、下面 C++代码实现了某种排序算法,其中代码片段 my_sort(arr, begin, i);my_sort(arr, i + 1, end);采用的算法思想是( )。

void my_sort(int arr[], int begin, int end) {
	if (begin >= end - 1) return;
	int i = begin, j = end - 1, x = arr[begin];
	while (i < j){
		while (i < j && arr[j] >= x)
			j--;
		if (i < j)
			arr[i++] = arr[j];
		
		while (i < j && arr[i] < x)
			i++;
		if (i < j)
			arr[j--] = arr[i];
	}
	arr[i] = x;
	my_sort(arr, begin, i);
	my_sort(arr, i + 1, end);
}
A.递推
B.贪心
C.分治
D.搜索

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

1、 质数的判定和筛法的目的并不相同,质数判定旨在判断特定的正整数是否为质数,而质数筛法意在筛选出范围内的所有质数。

2、 唯一分解定理指的是分解质因数只有唯一的一种算法。

3、一般情况下,在 C++中定义一个类时,构造函数和析构函数都不是必须手动定义的。

4、如果一个对象具有另一个对象的性质,那么它们之间就是继承关系。

5、哈夫曼编码树中,两个频率相同的字符一定具有相同的哈夫曼编码。

6、宽度优先搜索算法的英文简写是 BFS。

7、 深度优先遍历算法的时间复杂度为𝑂(𝑁 log 𝑁),其中𝑁为树的节点数。

8、任意二叉树都至少有一个结点的度是 2。

9、将𝑁个数据按照从小到大顺序存放在一个单向链表中。如果采用二分查找,那么查找的平均时间复杂度是𝑂(log 𝑁)。

10、深度优先遍历一般需要借助数据结构栈来实现,广度优先遍历一般需要借助数据结构队列来实现。

编程题 (每题 25 分,共 50 分)

下楼梯

【问题描述】
顽皮的小明发现,下楼梯时每步可以走 1 个台阶、2 个台阶或 3 个台阶。现在一共有𝑁个台阶,你能帮小明算算有多少种方案吗?
【输入描述】
输入一行,包含一个整数𝑁。约定1 ≤ 𝑁 ≤ 60。
【输出描述】
输出一行,包含一个整数𝐶,表示方案数。
【样例输入 1】
4
【样例输出 1】
7
【样例输入 2】
10
【样例输出 2】
274

亲朋数

【问题描述】
给定一串长度为𝐿、由数字 0-9 组成的数字串𝑆。容易知道,它的连续子串共有 L ( L + 1 ) 2 \frac{L(L+1)}{2} 2L(L+1)个。如果某个子串对应的数(允许有前导零)是𝑝的倍数,则称该子串为数字串𝑆对于𝑝的亲朋数。
例如,数字串𝑆为“12342”、𝑝为 2,则在 15 个连续子串中,亲朋数有“12”、“1234”、“12342”、“2”、“234”、“2342”、“34”、“342”、“4”、“42”、“2”等共 11 个。注意其中“2”出现了 2 次,但由于其在𝑆中的位置不同,记为不同的亲朋数。
现在,告诉你数字串𝑆和正整数𝑝,你能计算出有多少个亲朋数吗?
【输入描述】
输入的第一行,包含一个正整数𝑝。约定2 ≤ 𝑝 ≤ 128。
输入的第二行,包含一个长为𝐿的数字串𝑆。约定1 ≤ 𝐿 ≤ 106
【输出描述】
输出一行,包含一个正整数𝐶,表示亲朋数的个数。
【样例输入 1】
2
102
【样例输出 1】
5
【样例解释 1】
5 个亲朋数,分别为“10”、“102”、“0”、“02”、“2”。
【样例输入 2】
2
12342
【样例输出 2】
11

参考答案

单选题

题号123456789101112131415
答案ABCCDCABDDCCCBC

判断题

题号12345678910
答案××××××

编程题1

#include <iostream>

using namespace std;
long long downstair_record[61];
long long downstair(int n) {
	if (n == 0)
		return 1;
	if (downstair_record[n] > 0)
		return downstair_record[n];
	long long res = 0;
	if (n >= 1)
		res += downstair(n - 1);
	if (n >= 2)
		res += downstair(n - 2);
	if (n >= 3)
		res += downstair(n - 3);
	downstair_record[n] = res;
	return res;
}
int main() {
	for (int i = 0; i <= 60; i++)
		downstair_record[i] = -1;
	int n = 0;
	cin >> n;
	cout << downstair(n) << endl;
	return 0;
}

编程题2

#include <iostream>

using namespace std;
char S[1000001];
long long st_old[128];
long long st_new[128];
int main() {
	int p = 0;
	cin >> p;
	cin >> S;
	for (int i = 0; i < p; i++)
		st_old[i] = 0;
	long long res = 0;
	for (int t = 0; S[t] != '\0'; t++) {
		for (int i = 0; i < p; i++)
			st_new[i] = 0;
		int d = S[t] - '0';
		for (int i = 0; i < p; i++)
			st_new[(i * 10 + d) % p] += st_old[i];
		st_new[d % p]++;
		res += st_new[0];
		for (int i = 0; i < p; i++)
			st_old[i] = st_new[i];
	}
	cout << res << endl;
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

青岛少儿编程-王老师

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值