2025年09月GESPC++五级真题解析(含视频)

视频讲解:GESP2025年9月五级C++真题讲解

一、单选题

第1题

解析:

答案B,链表的插入删除操作更合适,数组的随机访问更合适

第2题

解析:

答案C,

cpp 复制代码
//保持cur的next
Node* del = cur->next;
//cur的next 指向下下个
cur->next = del->next;
//删除原来cur的next
delete del;

第3题

解析:

答案A,

cpp 复制代码
slow走1步
slow = slow->next
fast走2步
fast = fast->next->next

第4题

解析:

答案B,

cpp 复制代码
sum+=i;  //累加当前因数
if(i != n/i) sum+=n/i;  //累加对应的大因数
循环所有小因数即可
例如28有因数1 2 4 7 14
循环2至根号28,即  2 3 4 5 ,只有 2、4为因数,累加2 4 和对应的大因数 14 7

第5题

解析:

答案B,

cpp 复制代码
当除数b为0时,被除数a为最大公约数,例如:
a/b
9/6=1......3
6/3=2......0
3/0

第6题

解析:

答案C,标记i的所有倍数为不是质数,从i的平方开始,即i*i,之前小的倍数都被更小的质数标记了

cpp 复制代码
例如如下
i:2时
数字:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15....
标记:0 0 0 1 0 1 0 1 0 1  0  1  0  1  0
i:3时,从9开始即可,3的两倍被i为2标记过了
数字:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15....
标记:0 0 0 1 0 1 0 1 1 1  0  1  1  1  1

第7题

解析:

答案A,线性筛,通过最小的质因数去标记,一旦发现i是质数p的因数,就可以停止标记了

cpp 复制代码
例如
i为2时,质数有:2。标记2*2=4
数字:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15...
下标:0 0 0 1 0 0 0 0 0 0  0  0  0  0  0  0

i为3时,质数有:2,3。标记3*2=6,3*3=9
数字:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15...
下标:0 0 0 1 0 1 0 0 1 0  0  0  0  0  0  0

i为4时,质数有:2,3。标记4*2=8
因为4%2==0,4*3=12没必要标记,12会被6*2标记
数字:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15...
下标:0 0 0 1 0 1 0 1 1 0  0  0  0  0  0  0

第8题

解析:

答案B,只求素数,埃筛更快,最小质因子 / 欧拉函数 / 莫比乌斯函数时用线筛才更好

cpp 复制代码
bool isp[10000001];
vector<int> primes;
void sieve(int n){
    for(int i=2;i<=n;i++) isp[i]=1;
    for(int i=2;i<=n/i;i++) //只求素数,埃筛可大大缩小范围
        if(isp[i])
            for(int j=i*i;j<=n;j+=i) isp[j]=0;
    for(int i=2;i<=n;i++) if(isp[i]) primes.push_back(i);
}

int minp[10000001];
vector<int> primes;
void linsieve(int n){
    for(int i=2;i<=n;i++){  //线筛只能老老实实全部循环
        if(!minp[i]) minp[i]=i, primes.push_back(i);
        for(int p: primes){
            if(p>minp[i] || 1LL*i*p>n) break;
            minp[i*p]=p;
        }
    }
}

第9题

解析:

答案B,例如12能分解成的质因数2*2*3,不考虑顺序,只有一种

第10题

解析:

答案C,

cpp 复制代码
if( countLE(matrix,mid) >= k ){ //中间值>=k
    hi=mid;//保留这一行
}else{// 中间值<k
    lo=mid+1//往更大去找
}

第11题

解析:

答案D,基准元素最后要和i做交换,所以i要保持是小的那一边,所以得先移动j

cpp 复制代码
最初
i
4 2 8 6 1 8 9
            j
第1次:先移动i,在移动j
    i
4 2 8 6 1 8 9
        j
交换后:
    i
4 2 1 6 8 8 9
        j
第2次:先移动i,在移动j
      i
4 2 1 6 8 8 9
    j
交换后:6 4交换快速排序错误
      i
6 2 1 4 8 8 9
    j

第12题

解析:

答案D,由第4行可知,j的尽头在right,这里要循环剩余的所以j元素,所有要循环到j的尽头,即j<=right

第13题

解析:

答案B,贪心算法,哪个电影最早结束,排哪个在前面,即a1<b1,1代表结束时间,排完这个电影,需要更新结束时间,即lastEnd = moviesi1;

第14题

解析:

答案B,用分治实现,不是贪心

第15题

解析:

答案A,digitsi=9,9+1进位了,所以digitsi=0

二、判断题

第1题

解析:

答案√,两个函数的功能符合预期,在isDivisibleBy9是true的情况下,isDivisibleBy9(n) == isDigitSumDivisibleBy9(n)能够正确判断

复制代码
//函数判断 能否被9整除
bool isDivisibleBy9(int n) {
    return n % 9 == 0;
}
//函数计算各个位数之和能否被9整除
bool isDigitSumDivisibleBy9(int n) {
    int sum = 0;
    string numStr = to_string(n);//转为字符串
    for (char c : numStr) {//循环字符串
        sum += (c - '0');//转为int 进行累加
    }
    return sum % 9 == 0;
}

第2题

解析:

答案×,gcd(hm1,hm2)=2 ,(hm1*hm2)/com=(6*2)/2=6

第3题

解析:

答案×,当斐波那契数出现过,函数不会递归了,时间复杂度是O(n)

第4题

解析:

答案√,

复制代码
链表插入删除,通过改前驱和后驱结点,O(1)就能完成
链表的结点访问,没有下标,只能遍历整个链表查找,效率低
链表的结点存储,需要存储数据+指针,占用内存多
链表存储在随机位置,CPU访问时回同时访问附近的数据,存入缓存,导致缓存利用不友好

第5题

解析:

答案√,二分查找的前提是数组有序,每次需要获取正中间,需要依赖数组的下标实现,不可以用链表

第6题

解析:

答案√,线性筛的时间复杂度是O(n),埃氏筛的时间复杂度是O(nloglogn)

第7题

解析:

答案×,只有选择、快速、希尔、堆排序不稳定

第8题

解析:

答案×,dfs函数每次再调用2次dfs,时间复杂度是O(2^n)

第9题

解析:

答案√,任何递归可以改成while,任何while可以改成for

复制代码
//递归计算阶乘 
int f(int n){
	if(n<=1) return 1;
	return n*f(n-1);
} 
//递归改成while 
int n=5,ans=1;
while(n>1){
	ans*=n--;
}
//while改成for 
int ans=1;
for(int n=5;n>1;n--) ans*=n;

第10题

解析:

答案×,

复制代码
例如1/3/4 面值硬币凑6元(可能少的硬盘)
贪心第1个硬币用4,之后只能4 1 1凑出6
真正全局最优解是 3 3凑出6

三、编程题

第1题 GESP202509 五级 数字选取

题目描述

给定正整数 n,现在有 1,2,...,n 共计 n 个整数。你需要从这 n 个整数中选取一些整数,使得所选取的整数中任意两个不同的整数均互质(也就是说,这两个整数的最大公因数为 1)。请你最大化所选取整数的数量。

例如,当 n=9 时,可以选择 1,5,7,8,9 共计 5 个整数。可以验证不存在数量更多的选取整数的方案。

输入格式

一行,一个正整数 n,表示给定的正整数。

输出格式

一行,一个正整数,表示所选取整数的最大数量。

输入输出样例

输入 #1

复制代码
6

输出 #1

复制代码
4

输入 #2

复制代码
9

输出 #2

复制代码
5

说明/提示

对于 40% 的测试点,保证 1≤n≤1000。

对于所有测试点,保证 1≤n≤10^5。

答案

cpp 复制代码
#include <bits/stdc++.h>
using namespace std;
int main() {
	//1)确定范围n
	int n;cin>>n;
	//2)埃筛2至n
	int ans=1;//包括1 
	//初始化所有为false,假设所有都是质数 
	bool flag[100010]={}; 
	for(int i=2;i<=n;i++){
		//是质数,将所有倍数标记为不是质数 
		if(flag[i]==false){
			for(int j=2*i;j<=n;j+=i){
				flag[j]=true;
			} 
			//3)是质数 ,+1 
			ans++; 
		} 	
	} 
	cout<<ans;
}

第2题 GESP202509 五级 有趣的数字和

题目描述

如果一个正整数的二进制表示包含奇数个 1,那么小 A 就会认为这个正整数是有趣的。

例如,7 的二进制表示为 (111)2​,包含 1 的个数为 3 个,所以 7 是有趣的。但是 9=(1001)2​ 包含 2 个 1,所以 9 不是有趣的。

给定正整数 l,r,请你统计满足 l≤n≤r 的有趣的整数 n 之和。

输入格式

一行,两个正整数 l,r,表示给定的正整数。

输出格式

一行,一个正整数,表示 l,r 之间有趣的整数之和。

输入输出样例

输入 #1

cpp 复制代码
3 8

输出 #1

cpp 复制代码
19

输入 #2

cpp 复制代码
65 36248

输出 #2

cpp 复制代码
328505490

说明/提示

【数据范围】

对于 40% 的测试点,保证 1≤l≤r≤10^4。

对于另外 30% 的测试点,保证 l=1 并且 r=2k−1,其中 k 是大于 1 的正整数。

对于所有测试点,保证 1≤l≤r≤10^9。

【提示】

由于本题的数据范围较大,整数类型请使用 long long。

答案

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
long long cal(int x){//65 
	//计算出周期0-63
	long long end= (x+1)-(x+1)%4-1;
	// 0至63周期和
	long long ans=(0+end)*(end+1)/4;
	//特殊处理 超出的64 65
	for(long long i=end+1;i<=x;i++){
		int count=0;
		int temp=i;
		while(temp){
			if(temp&1) count++;
			temp>>=1;
		}
		if(count%2==1) ans+=i;
	}
	//返回结果 
	return ans;
}
int main(){
	int L,R;
	cin>>L>>R;
	cout<<cal(R)-cal(L-1);
}
相关推荐
倒头就睡的小比特3 天前
算法竞赛C++常用的STL
c++·算法
小羊没烦恼!3 天前
初探性能优化——2个月到4小时的性能提升
java·开发语言·windows·算法·c#
猎头南楼3 天前
知识社区推荐系统实践:新用户冷启动与长短期兴趣建模的挑战 资深推荐算法工程师
人工智能·深度学习·算法·机器学习
旖旎夜光3 天前
力控面试题 01.01: 判定字符是否唯一(位运算) —— 题解
c++·学习·算法·leetcode·力控
wzdark3 天前
大规模并行计算中的负载均衡算法研究4
算法
Because_of_Her13 天前
并查集-听课笔记
笔记·算法·并查集
码流子3 天前
高速公路安全监测实践:碰撞监测预警+物联网底座,从感知到处置的闭环
大数据·人工智能·物联网·算法·架构
another heaven3 天前
【算法/C++ MD5算法能否逆解码?原理、C++实现与同类哈希算法对比】
c++·算法·哈希算法
wzdark3 天前
从算法设计模式看编程思维的抽象能力4
算法
2601_962218613 天前
万象生鲜系统称重自动多退少补算法解决生鲜非标品痛点
大数据·数据库·人工智能·python·算法