2026年6月GESP真题及题解(C++五级): 选择题和判断题(题解)
选择题
第1题
题目:假设head != nullptr,下面是实现单向循环链表在头节点后插入新节点的代码,横线处应填入()。
structNode{intval;Node*next;};voidinsertAfterHead(Node*head,intx){Node*newNode=newNode;newNode->val=x;// 横线处}答案:B
解析:在头节点后插入新节点,应先把新节点的next指向原来的头节点后继,再让头节点指向新节点。即:
newNode->next=head->next;head->next=newNode;第2题
题目:下面代码遍历并输出一个循环单链表,其中head指向链表的第一个节点,横线处应填入的是()。
structNode{intval;Node*next;};voidprintList(Node*head){if(head==nullptr)return;Node*p=head;// 在此处填入代码cout<<endl;}答案:C
解析:循环单链表不能用p != nullptr作为结束条件,否则会死循环。应使用do-while,先输出当前节点,再移动到下一个节点,直到回到head。
do{cout<<p->val<<" ";p=p->next;}while(p!=head);第3题
题目:双链表结点定义如下,若要删除双链表中的中间结点(非首尾节点)p,下面写法正确的是()。
structNode{intval;Node*prev;Node*next;};答案:A
解析:删除双链表中间节点p,需要让p的前驱指向p的后继,让p的后继回指p的前驱,最后释放p。
p->prev->next=p->next;p->next->prev=p->prev;deletep;第4题
题目:使用如下欧几里得算法求gcd(105, 45)时,函数gcd(a, b)的递归调用序列正确的是()。
intgcd(inta,intb){returnb==0?a:gcd(b,a%b);}答案:B
解析:
gcd(105, 45) = gcd(45, 105 % 45) = gcd(45, 15) = gcd(15, 45 % 15) = gcd(15, 0) = 15因此调用序列为:gcd(105,45) -> gcd(45,15) -> gcd(15,0)。
第5题
题目:下面代码实现线性筛(欧拉筛),以筛选出n以内的所有素数。横线处的代码应为()。
vector<int>sieve(intn){vector<bool>is_prime(n+1,true);vector<int>primes;if(n>=0)is_prime[0]=false;if(n>=1)is_prime[1]=false;for(inti=2;i<=n;++i){if(is_prime[i]){primes.push_back(i);}for(intj=0;j<primes.size()&&i*primes[j]<=n;j++){is_prime[i*primes[j]]=false;if(/* 在此处填入代码 */)break;}}returnprimes;}答案:A
解析:线性筛要求每个合数只被它的最小质因子筛掉。当i % primes[j] == 0时,说明primes[j]是i的最小质因子,后面的素数不应再继续筛,否则会导致重复标记。
if(i%primes[j]==0)break;第6题
题目:下面关于埃氏筛法的说法正确的是()。
答案:B
解析:埃氏筛法的基本思想是:从每个素数出发,把它的倍数标记为合数。
A 错,埃氏筛法会重复筛掉某些合数;C、D 明显错误。
第7题
题目:下面代码实现了计算x^n的快速幂算法,该算法体现的编程思想是()。
longlongpower(longlongx,intn){if(n==0)return1;longlongres=power(x,n/2);if(n%2==0)returnres*res;elsereturnres*res*x;}答案:C
解析:快速幂将x^n分解为x^(n/2)的子问题,再根据奇偶性合并结果,体现了分治思想。
第8题
题目:下面代码用于统计n中因子 2 出现了多少次。若n = 40,输出是()。
intn=40;intcnt=0;while(n%2==0){cnt++;n/=2;}cout<<cnt;答案:C
解析:
40 / 2 = 20 cnt = 1 20 / 2 = 10 cnt = 2 10 / 2 = 5 cnt = 3 5 % 2 != 0,停止所以输出3。
第9题
题目:在一个有序数组中查找第一个大于或等于x的元素位置,横线处应填写()。
intlowerBound(vector<int>&a,intx){intl=0,r=a.size();while(l<r){intmid=l+(r-l)/2;if(a[mid]>=x)// 在此处填入代码elsel=mid+1;}returnl;}答案:C
解析:当a[mid] >= x时,说明第一个大于或等于x的位置可能是mid,也可能在mid左边,因此应令r = mid。
第10题
题目:有若干根木头,长度存于wood。每切一刀可以把一段木头分成两段。函数check(wood, K, x)返回:用不超过K刀,能否使所有木段长度都不超过x。下面代码使用二分答案查找最小可行的x,横线处应填()。
intbinary_cut(vector<int>&wood,intK){intl=1;intr=0;for(intlen:wood)r=max(r,len);while(l<r){intmid=l+(r-l)/2;if(check(wood,K,mid))// 横线处elsel=mid+1;}returnl;}答案:B
解析:如果mid可行,说明答案可能是mid或更小,因此要缩小右边界:
r=mid;第11题
题目:下面代码段实现了快速排序的划分操作(以首元素为基准),横线处代码应填入()。
intpartition(vector<int>&arr,intlow,inthigh){intpivot=arr[low];inti=low,j=high;while(i<j){while(i<j&&arr[j]>=pivot)j--;while(i<j&&arr[i]<=pivot)i++;if(i<j)swap(arr[i],arr[j]);}// 在此处填入代码returni;}答案:B
解析:划分结束后,i指向基准元素应该放置的位置。基准一开始在arr[low],因此应交换arr[low]和arr[i]:
swap(arr[low],arr[i]);第12题
题目:下面哪句话最符合归并排序的思想?()
答案:B
解析:归并排序的核心思想是:将数组分成两半分别排序,然后再将两个有序部分合并成一个有序数组。
第13题
题目:在对长度为n(n >= 1)的数组进行归并排序的过程中,mergeArray函数(合并两个有序子数组的操作)被调用的次数是()。
答案:A(n - 1)
解析:归并排序的递归过程中,每个内部节点对应一次mergeArray调用。长度为n的数组最终合并成一个有序数组,内部节点共有n - 1个,因此mergeArray被调用n - 1次。
当n = 1时,调用0次,也符合n - 1。
第14题
题目:下面代码用于计算最少箱子数,横线处应填入()。
intminBoxes(vector<int>&w,intlimit){sort(w.begin(),w.end());intl=0,r=w.size()-1;intboxes=0;while(l<=r){if(w[l]+w[r]<=limit){// 在此处填入代码}else{r--;}boxes++;}returnboxes;}答案:C
解析:如果最轻的w[l]和最重的w[r]能放入同一个箱子,则两人同箱,左右指针都要移动:
l++;r--;第15题
题目:高精度减法中,假设两个高精度数按低位在前存储,且已经保证被减数不小于减数。下面处理借位逻辑代码中横线处应填入()。
if(a[i]<b[i]){a[i+1]--;// 横线处}t=a[i]-b[i];答案:A
解析:当前位不够减时,向高位借1,当前位相当于加10,因此应执行:
a[i]+=10;判断题
第1题
题目:数组的存储空间在物理上通常是连续的,而链表的结点可以存储在不连续的内存空间中。
答案:√
解析:数组通常采用连续内存空间存储;链表节点通过指针连接,物理上可以不连续。
第2题
题目:带哨兵头尾节点的双向循环链表,在表头插入节点p,以下四步操作无论什么顺序执行结果都正确。
p->next=head->next;p->prev=head;head->next->prev=p;head->next=p;答案:×
解析:链表指针修改有顺序依赖,不能任意顺序执行。
例如若先执行head->next = p,则原来的head->next已经丢失,后续head->next->prev = p会变成对p->prev的操作,破坏链表结构。
第3题
题目:对任意正整数a、b,以下两种写法的gcd函数返回值完全相同。
intgcd1(inta,intb){returnb?gcd1(b,a%b):a;}intgcd2(inta,intb){while(b){intt=b;b=a%b;a=t;}returna;}答案:√
解析:两者都实现了欧几里得算法。gcd1使用递归,gcd2使用迭代,最终都会在b == 0时返回a,因此返回值相同。
第4题
题目:在归并排序的合并操作中,如下代码片段可以正确地将两个已排序的子数组 L 和 R 合并回原数组 arr 中。
voidmerge(intarr[],intleft,intmid,intright){intn1=mid-left+1;intn2=right-mid;vector<int>L(n1),R(n2);for(inti=0;i<n1;i++)L[i]=arr[left+i];for(intj=0;j<n2;j++)R[j]=arr[mid+1+j];inti=0,j=0,k=left;while(i<n1&&j<n2){if(L[i]<=R[j])arr[k++]=L[i++];elsearr[k++]=R[j++];}while(i<n1)arr[k++]=L[i++];while(j<n2)arr[k++]=R[j++];}答案:√
解析:该代码是标准的归并排序合并(Merge)操作实现。它首先计算两个子数组的长度n1和n2,然后分别将它们复制到临时数组L和R中。接着使用双指针i和j遍历两个临时数组,比较当前元素,将较小的元素放回原数组arr中(<=保证了排序的稳定性)。最后将剩余未处理的元素依次复制回原数组。代码逻辑正确,边界处理无误。
第5题
题目:分治法通常将一个规模较大的问题拆分为若干个规模较小、结构相似的子问题,分别求解后再合并子问题的结果。
答案:√
解析:分治法(Divide and Conquer)的核心思想就是“分而治之”。它将一个难以直接解决的大问题,分割成一些规模较小的相同问题,以便各个击破,分而治之。通常包含三个步骤:分解(Divide)、解决(Conquer)和合并(Combine)。题干描述完全符合分治法的定义。
第6题
题目:贪心算法只要每一步选择当前最优解,就一定能得到全局最优解。
答案:×
解析:贪心算法的核心是在每一步选择中都采取在当前状态下最好或最优(即最有利)的选择,从而希望导致结果是最好或最优的算法。然而,局部最优解的总和并不总是等于全局最优解。贪心算法只有在问题满足“贪心选择性质”和“最优子结构性质”时,才能保证得到全局最优解。例如,在找零钱问题中,如果硬币面值设计不当,贪心策略可能会失败。
第7题
题目:二分查找不仅可以应用于有序数组,也可以在不增加时间复杂度的情况下应用于有序的单链表,因为链表也支持 O(1) 时间内的随机访问。
答案:×
解析:二分查找的核心在于能够以 O(1) 的时间复杂度随机访问中间元素。数组支持 O(1) 随机访问,因此二分查找的时间复杂度为 O(log n)。但是,单链表不支持 O(1) 随机访问,访问第 k 个元素需要从头遍历,时间复杂度为 O(k)。如果对单链表进行二分查找,每次计算mid后都需要 O(n) 的时间遍历找到中间节点,总时间复杂度会退化到 O(n log n) 甚至 O(n)。因此,二分查找不适用于单链表。
第8题
题目:以下函数 f1 的时间复杂度比函数 f2 的更高。
voidf1(intn){for(inti=1;i<n;i*=2);}voidf2(intn){if(n<=1)return;f2(n-1);f2(n-1);}答案:×
解析:
- 函数
f1中的循环变量i每次乘以 2,循环执行次数为 log₂n 次,因此时间复杂度为O(log n)。 - 函数
f2是一个递归函数,每次调用自身两次,且规模减 1。其递推式为 T(n) = 2T(n-1) + O(1),展开后时间复杂度为O(2ⁿ)。 - 显然,O(2ⁿ) 远大于 O(log n)。因此,
f2的时间复杂度比f1更高,题干说法错误。
第9题
题目:唯一分解定理表明,任何一个大于 1 的自然数都可以唯一地分解为若干个质数的乘积,如果不考虑质因数的顺序,这种分解方式是唯一的。
答案:√
解析:唯一分解定理(又称算术基本定理)指出:任何一个大于 1 的自然数,都可以唯一分解成有限个质数的乘积。如果不考虑这些质因数的排列顺序,这种分解方式是唯一的。例如,( 360 = 2^3 \times 3^2 \times 5 ),除此之外没有其他质因数分解方式。题干表述正确。
第10题
题目:归并排序和快速排序在平均情况下的时间复杂度均为 O(n log n)。但在稳定性方面,归并排序通常是不稳定的、而快速排序是稳定的。
答案:×
解析:题干中关于稳定性的描述完全说反了。
- 归并排序:在合并两个有序子数组时,如果元素相等,代码通常先取左半部分的元素(如第4题代码中的
L[i] <= R[j]),这保证了相等元素的相对顺序不变,因此归并排序是稳定的。 - 快速排序:在划分过程中,可能会跨越多个元素进行交换,这很容易破坏相等元素的相对顺序(例如序列
[2, 2, 1]),因此快速排序通常是不稳定的。
各种学习资料,助力大家一站式学习和提升!!!
#include<bits/stdc++.h>usingnamespacestd;intmain(){cout<<"########## 一站式掌握信奥赛知识! ##########";cout<<"############# 冲刺信奥赛拿奖! #############";cout<<"###### 课程购买后永久学习,不受限制! ######";return0;}【秘籍汇总】(完整csp信奥赛C++学习资料):
1、csp/信奥赛C++,完整信奥赛系列课程(永久学习):
https://edu.csdn.net/lecturer/7901 点击跳转
2、CSP信奥赛C++竞赛拿奖视频课:
https://edu.csdn.net/course/detail/40437 点击跳转
https://edu.csdn.net/course/detail/41081 点击跳转
3、csp信奥赛高频考点知识详解及案例实践:
CSP信奥赛C++动态规划:
https://blog.csdn.net/weixin_66461496/category_13096895.html点击跳转
CSP信奥赛C++标准模板库STL:
https://blog.csdn.net/weixin_66461496/category_13108077.html 点击跳转
信奥赛C++提高组csp-s知识详解及案例实践:
https://blog.csdn.net/weixin_66461496/category_13113932.html 点击跳转
4、csp信奥赛冲刺一等奖有效刷题题解:
信奥赛C++普及组CSP-J一等奖通关刷题题单及题解:
https://blog.csdn.net/weixin_66461496/category_12673810.html 点击跳转
信奥赛C++普及组csp-j初赛&复赛真题题解(持续更新):https://blog.csdn.net/weixin_66461496/category_12808781.html 点击跳转
信奥赛C++提高组csp-s初赛&复赛真题题解(持续更新):
https://blog.csdn.net/weixin_66461496/category_13125089.html 点击跳转
5、GESP C++考级真题题解:
GESP(C++ 一级+二级+三级)真题题解(持续更新):https://blog.csdn.net/weixin_66461496/category_12858102.html 点击跳转
GESP(C++ 四级+五级+六级)真题题解(持续更新):https://blog.csdn.net/weixin_66461496/category_12869848.html 点击跳转
GESP(C++ 七级+八级)真题题解(持续更新):
https://blog.csdn.net/weixin_66461496/category_13117178.html 点击跳转
· 文末祝福 ·
#include<bits/stdc++.h>usingnamespacestd;intmain(){cout<<"跟着王老师一起学习信奥赛C++";cout<<" 成就更好的自己! ";cout<<" csp信奥赛一等奖属于你! ";return0;}