GESP 2025年6月_C++五级试卷
从PDF导入:GESP 2025年6月_C++五级试卷
试卷题目预览
与数组相比,链表在( )操作上通常具有更高的效率。
下面C++代码实现双向链表。函数is_empty()判断链表是否为空,如链表为空返回true,否则返回false。横线处不能填写( )。

基于上题代码正确的前提下,填入相应代码完善append(),用于在双向链表尾部增加新节点,横线上应填写( )。

下列C++代码用循环链表解决约瑟夫问题,即假设n个人围成一圈,从第一个人开始数,每次数到第k个的人就出圈,输出最后留下的那个人的编号。横线上应填写( )。
struct Node {
int data;
Node* next;
};
Node* createCircularList(int n) {
Node* head = new Node{1, nullptr};
Node* prev = head;
for (int i = 2; i <= n; ++i) {
Node* node = new Node{i, nullptr};
prev->next = node;
prev = node;
}
prev->next = head;
return head;
}
int fingLastSurvival(int n, int k) {
Node* head = createCircularList(n);
Node* p = head;
Node* prev = nullptr;
while (p->next != p) {
for (int count = 1; count < k; ++count) {
prev = p;
p = p->next;
}
_______________________
}
cout << "最后留下的人编号是: " << p->data << endl;
delete p;
return 0;
}
下列C++代码判断一个正整数是否是质数,说法正确的是( )。
bool is_prime(int n) {
if (n <= 1)
return false;
if (n == 2 || n == 3 || n == 5)
return true;
if (n % 2 == 0 || n % 3 == 0 || n % 5 == 0)
return false;
int i = 7;
int step = 4;
int finish_number = sqrt(n) + 1;
while (i <= finish_number) {
if (n % i == 0)
return false;
i += step;
step = 6 - step;
}
return true;
}
下列C++代码用两种方式求解两个正整数的最大公约数,说法错误的是( )。

下面的代码用于判断整数是否是质数,错误的说法是( )。

唯一分解定理描述了关于正整数的什么性质?
下面的C++代码,用于求一系列数据中的最大值。有关其算法说法错误的是( )。

下面的C++代码,用于求一系列数据中的最大值。有关其算法说法错误的是( )。

下面的C++代码用于在升序数组lst中查找目标值target最后一次出现的位置。相关说法,正确的是( )。

有关下面C++代码的说法,错误的是( )。
double sqrt_binary(long long n, double epsilon = 1e-10) {
if (n < 0) {
throw invalid_argument("输入必须为非负整数");
}
if (n == 0 || n == 1) return n;
// 阶段 1
long long low = 1, high = n;
long long k = 0;
while (low <= high) {
long long mid = (low + high) / 2;
long long mid_sq = mid * mid;
if (mid_sq == n) {
return mid;
} else if (mid_sq < n) {
k = mid;
low = mid + 1;
} else {
high = mid - 1;
}
}
long long next_k = k + 1;
if (next_k * next_k == n) {
return next_k;
}
// 阶段 2
double low_d = (double)k;
double high_d = (double)(k + 1);
double mid;
while (high_d - low_d >= epsilon) {
mid = (low_d + high_d) / 2;
double mid_sq = mid * mid;
if (mid_sq < n) {
low_d = mid;
} else {
high_d = mid;
}
}
double result = (low_d + high_d) / 2;
long long check_int = (long long)(result + 0.5);
if (check_int * check_int == n) {
return check_int;
}
return result;
}
硬币找零问题中要求找给客户最少的硬币。 coins 存储可用硬币规格,单位为角,假设规格都小于10角,且一定有1角规格。 amount 为要找零的金额,约定必须为1角的整数倍。输出为每种规格及其数量,按规格从大到小输出,如果某种规格不必要,则输出为0。下面是其实现代码,相关说法正确的是( )。
const int MAX_COINS = 10;
int result[MAX_COINS] = {0}; // 假设最多10种面额
int find_coins(const vector<int>& coins, int amount) {
sort(coins.begin(), coins.end(), greater<int>());
int n = coins.size();
for (int i = 0; i < n; ++i) {
int coin = coins[i];
int num = amount / coin;
result[i] = num;
amount -= num * coin;
if (amount == 0) break;
}
cout << "找零方案如下:" << endl;
for (int i = 0; i < n; ++i) {
cout << sorted_coins[i] << "角需要" << result[i] << "枚" << endl;
}
return 0;
}
关于下述C++代码的快速排序算法,说法错误的是( )。

小杨编写了一个如下的高精度除法函数,则横线上应填写的代码为( )。



下面C++代码是用欧几里得算法(辗转相除法)求两个正整数的最大公约数,a大于b还是小于b都适用。

假设函数gcd()函数能正确求两个正整数的最大公约数,则下面的lcm()函数能求相应两数的最小公倍数。

下面的C++代码用于输出每个数对应的质因数列表。

下面的C++代码实现归并排序。代码在执行时,将输出一次HERE字符串,因为merge()函数仅被调用一次。
void merge(std::vector<int>& arr, int left, int mid, int right) {
std::vector<int> temp(right - left + 1);
int i = left;
int j = mid + 1;
int k = 0;
while (i <= mid && j <= right) {
if (arr[i] <= arr[j]) {
temp[k++] = arr[i++];
} else {
temp[k++] = arr[j++];
}
}
while (i <= mid) {
temp[k++] = arr[i++];
}
while (j <= right) {
temp[k++] = arr[j++];
}
for (int p = 0; p < k; ++p) {
arr[left + p] = temp[p];
}
}
void mergeSort(std::vector<int>& arr, int left, int right) {
if (left >= right) {
return;
}
int mid = left + (right - left) / 2;
mergeSort(arr, left, mid);
mergeSort(arr, mid + 1, right);
std::cout << "HERE";
merge(arr, left, mid, right);
}
归并排序的最好、最坏和平均时间复杂度均为O(n log n)。
查字典这个小学生必备技能,可以把字典视为一个已排序的数组。假设小杨要查找一个音首字母为 g 的单词,他首先翻到字典约一半的页数,发现该页的首字母是 m ,由于字母表中 g 位于 m 之前,所以排除字典后半部分,查找范围缩小到前半部分;不断重复上述步骤,直至找到首字母为 g 的页码。这种查字典的一系列操作可看作二分查找。
求解最短路径问题常用Dijkstra算法,从算法的描述可以看出,Dijkstra算法是贪心算法。
分治算法将原问题可以分解成规模更小的子问题,但由于分治算法需要将问题进行分解,所以分治算法的效率通常比直接求解原问题的效率低。
函数puzzle定义如下,则调用puzzle(7)程序会无限递归。

如下为线性筛法,用于高效生成素数表,其核心思想是每个合数只被它的最小质因数筛掉一次,时间复杂度为O(n)。
vector<int> linearSieve(int n) {
vector<bool> is_prime(n + 1, true);
vector<int> primes;
for (int i = 2; i <= n; ++i) {
if (is_prime[i]) {
primes.push_back(i);
}
for (int j = 0; j < primes.size() && i * primes[j] <= n; ++j) {
is_prime[i * primes[j]] = false;
if (i % primes[j] == 0) {
break;
}
}
}
return primes;
}
奖品兑换
班主任给上课专心听讲、认真完成作业的同学们分别发放了若干张课堂优秀券和作业优秀券。同学们可以使用这两种券找班主任兑换奖品。具体来说,可以使用a张课堂优秀券和b张作业优秀券兑换一份奖品,或者使用c张课堂优秀券和d张作业优秀券兑换一份奖品。
现在小A有n张课堂优秀券和m张作业优秀券,他最多能兑换多少份奖品呢?
第一行,两个正整数n, m,分别表示小A持有的课堂优秀券和作业优秀券的数量。 第二行,两个正整数a, b,表示兑换一份奖品所需的两种券的数量。
输出共一行,一个整数,表示最多能兑换的奖品份数。
【样例输入】 8 8 2 1 【样例输出】 5 对于50%的测试点,保证n,m<=1000,a,b<=100。 对于所有测试点,保证1<=n,m<=10^9,1<=a,b<=10^5。
最大公因数
对于两个正整数x,y,它们的最大公因数记为gcd(x,y)。对于n个正整数a1,a2,...,an,它们的最大公因数为:gcd(a1,a2,...,an) = gcd(gcd(...gcd(gcd(a1,a2),a3)...),an)。
给定n个正整数a1,a2,...,an以及q组询问。对于第i(1<=i<=q)组询问,请求出gcd(a1+i, a2+i, ..., an+i)。
第一行,两个正整数n, q,分别表示给定正整数的数量,以及询问组数。 第二行,n个正整数a1,a2,...,an。
输出共q行,第i行包含一个正整数,表示gcd(a1+i, a2+i, ..., an+i)。
【样例输入】 5 3 6 9 12 18 30 【样例输出】 1 3 1 对于50%的测试点,保证n,q<=5000,ai,q<=10^4。 对于所有测试点,保证n,q<=10^5,1<=ai<=10^9,1<=q<=10^5。