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);
}
相关推荐
白狐_79840 分钟前
408 数据结构|外部排序:流程与 k 路归并
数据结构·算法
闻缺陷则喜何志丹1 小时前
【动态规划】P3609 [USACO17JAN] Hoof, Paper, Scissor G
c++·算法·动态规划·洛谷
leihefeng1 小时前
手写数字识别:KNN vs 逻辑回归实战
python·算法·机器学习·逻辑回归·scikit-learn
全栈技术负责人2 小时前
DeepSeek Harness 业务工具权限插件 dsh-tool-permission设计思路
网络·算法·ai·ai编程
mmmmath_32 小时前
面试题 02.07. 链表相交
算法·链表
residual_fan2 小时前
特征级SMOTE(Feature-level SMOTE)论文分享
人工智能·算法·数据挖掘·数据分析
xxwxx__2 小时前
深入理解 C++ STL:stack、queue 与 deque 从使用到底层实现全解析
开发语言·c++·算法
sylviiiiiia3 小时前
Leetcode hot100 多数元素/相交链表/反转链表
算法·leetcode·链表
CoderYanger3 小时前
A.每日一题:3622. 判断整除性
java·程序人生·算法·leetcode·面试·职场和发展·蓝桥杯