欢迎大家订阅我的专栏:算法题解:C++与Python实现!
本专栏旨在帮助大家从基础到进阶 ,逐步提升编程能力,助力信息学竞赛备战!
专栏特色
1.经典算法练习:根据信息学竞赛大纲,精心挑选经典算法题目,提供清晰的代码实现与详细指导,帮助您夯实算法基础。
2.系统化学习路径:按照算法类别和难度分级,从基础到进阶,循序渐进,帮助您全面提升编程能力与算法思维。
适合人群:
- 准备参加蓝桥杯、GESP、CSP-J、CSP-S等信息学竞赛的学生
- 希望系统学习C++/Python编程的初学者
- 想要提升算法与编程能力的编程爱好者
附上汇总帖:GESP认证C++编程真题解析 | 汇总
单选题
第1题
小杨父母带他到某培训机构给他报名参加CCF组织的GESP认证考试的第1级,那他可以选择的认证语言有几种?( )
A.1
B.2
C.3
D.4
【答案】:C
【解析】
GESP考察有三种语言可选, 为图形化(Scratch)编程、Python编程及C++编程。
第2题
下面流程图在yr输入2024时,可以判定yr代表闰年,并输出2月是29天,则图中菱形框中应该填入( )。

A.(yr%400==0) || (yr%4==0)
B.(yr%400==0) || (yr%4==0 && yr%100!=0)
C.(yr%400==0) || (yr%4==0)
D.(yr%400==0) || (yr%4==0 && yr%100 !=0)
【答案】:B
【解析】
一个年份如果能被400整除,是闰年。
或者该年份能被4整除但不能被100整除,也是闰年。
A选项忽略了100的条件;C选项和D选项使用了逻辑与而非逻辑或,不符合闰年定义。正确答案是B选项。
第3题
在C++中,下列不可做变量的是( )。
A.five-Star
B.five_star
C.fiveStar
D._fiveStar
【答案】:A
【解析】
有效的变量名是由大小写字母、数字、下划线组成的任意长度的序列,且第一个字符不能为数字。另外,C++中有一一些关键字已被编程语言保留,不能用作变量名。
A选项的因包含非法字符-(连字符)而不符合C++变量命名规则。
第4题
在C++中, 与for(inti=0; i<10; i++) 效果相同的是( )。
A.for(int i=0; i<10; i+=1)
B.for(int i=1; i<=10; i++)
C.for(int i=10; i>0; i--)
D.for(int i=10; i<1; i++)
【答案】:A
【解析】
B选项初始值和终止条件不同;C选项循环方向相反;D选项的初始条件即不满足,不会循环。A选项与原始代码功能完全一致。
第5题
在C++中, cout << (5 % 2 && 5 % 3) 的输出是( )
A.1
B.2
C.true
D.false
【答案】:A
【解析】
先进行算数运算
表达式5%2:求5除以2的余数,结果为1。
表达式5%3:求5除以3的余数,结果为2。
然后进行逻辑运算:表达式5%2&&5%3等价于1&&2。
在C++中,做布尔运算时非布尔类型会转换为布尔类型,非零值都被转换为true, 零值会转换为false, 所以1&&2为true。
布尔值true输出时对应整数1, 因此最终输出为1。
综上所述, cout<<(5%2&&5%3) 的输出是1,故正确答案是A。
第6题
执行下面的C++代码时输入1,则输出是( )。
int month;cin >> month;switch(month) {case 1:cout << "Jan ";case 3:cout << "Mar ";break;default:;
}
A.Jan
B.Mar
C.Jan Mar
D.以上均不对
【答案】:C
【解析】
当month==1时, 程序执行case 1中的代码,即输出"Jan ", 由于没有break语句, 程序将继续执行下一个case。接着会执行case 3中的代码, 输出"Mar ", 然后遇到break语句, 跳出switch语句块。
因此, 当用户输入1时, 程序依次输出"Jan "和"Mar ", 最终结果为"Jan Mar"。
第7题
执行下面C++代码后,有关说法错误的是( )。
int a, b;
cin >> a >> b;
if (a && b)cout << "1";
else if (!(a || b))cout << "3";
elsecout << "4";
A.如果先后输入1和1,则将输出1
B.如果先后输入0和1或者1和0,则将输出3
C.如果先后输入0和0,则将输出2
D.如果先后输入0和0,则将输出4
【答案】:D
【解析】
如果输入0和0,则!(a||b)为真,输出“2"。
第8题
某货币由5元,2元和1元组成。输入金额(假设为正整数),计算出最少数量。为实现其功能,横线处应填入代码是( )。
int N;
cin >> N;
int MS, M2, M1;
MS = N / 5;
M2 = ____;
M1 = ____;
printf("5*%d+2*%d+1*%d", MS, M2, M1);
A.第1横线处应填入:N / 2
第2横线处应填入:N - M5 - M2
B.第1横线处应填入:(N - M5 * 5) / 2
第2横线处应填入:N - M5 * 5 - M2 * 2
C.第1横线处应填入:N - M5 * 5 / 2
第2横线处应填入:N - M5 * 5 - M2 * 2
D.第1横线处应填入:(N - M5 * 5) / 2
第2横线处应填入:N - M5 - M2
【答案】:B
【解析】
A选项没有考虑到5元硬币的影响;C选项表达式1的优先级错误;D 选项在第二个横线处没有正确减去所有已经使用的硬币数。B选项正确。首先用(N - M5 * 5) / 2计算2元硬币的数量,然后用N - M5 * 5 - M2 * 2计算1元硬币的数量。
第9题
下面C++代码执行后的输出是( )。
int loopCount = 0;
for (int i=0; i < 10; i++)for (int j=1; j < i; j++)loopCount += 1;
cout << loopCount;
A.55
B.45
C.36
D.28
【答案】:C
【解析】
当i=0时,内层循环不执行,因为j<0不成立。
当i=1时,内层循环也不执行,因为j<1不成立。
当i=2时,内层循环执行一次(j=1),所以loopCount增加1。
当i=3时,内层循环执行两次(j=1,2),所以loopCount增加2。
...
当i=9时,内层循环执行八次(j=1, 2, 3, 4, 5, 6, 7, 8) , 所以loopCount增加8。
总结增加次数为:1+2+3+4+5+6+7+8=36
因此, 最终loopCount的值是36, 对应的选项是C。
第10题
下面C++代码执行后的输出是( )。
int loopCount = 0;
for (int i=0; i < 10; i++) {for (int j=0; j < i; j++)if (i * j % 2)break;loopCount += 1;
}
cout << loopCount;
A.25
B.16
C.10
D.9
【答案】:C
【解析】
if语句和for语句只控制下面的第一个语句或第一个由{}包括所包含的语句块。外层循环从i=0到i=9, 一共会执行10次。loopCount在外层循环中,增加10次,最终值为10。
第11题
假设下面C++代码执行过程中仅输入正负整数或0,有关说法错误的是( )。
int N,Sum = 0;
cin >> N;
while (N) {Sum += N;cin >> N;
}
cout << Sum;
A.执行上面代码如果输入0,将终止循环
B.执行上面代码能实现所有非0整数的求和
C.执行上面代码第一次输入0,最后将输出0
D.执行上面代码将陷入死循环, 可将while(N) 改为while(N==0)
【答案】:D
【解析】
原代码在输入0时会正常退出循环,不会陷入死循环。
第12题
执行下面的C++代码,有关说法正确的是( )【质数是指仅能被1和它本身整除的正整数】。
int N;
cin >> N;
bool Flag = true;
for (int i=2; i < N; i++) {if (i * i > N)break;if (N % i == 0) {Flag = false;break;}
}
if (Flag)cout << N << "是质数" << endl;
elsecout << N << "不是质数" << endl;
A.如果输入正整数,上面代码能正确判断N是否为质数
B.如果输入整数,上面代码能正确判断N是否为质数
C.如果输入大于等于0的整数,上面代码能正确判断N是否质数
D.如将Flag=true修改为Flag=N>=2?true:false则能判断所有整数包括负整数、0、正整数是否为质数
【答案】:D
【解析】
原代码输入负数、0和1会输出错误的结果,D选项为三目运算,如果N大于等于2, Flag会被初始化为true否则被初始化为false。通过初始化Flag来处理小于2的特殊情况,从而能够正确判断所有整数是否为质数
第13题
下面C++代码用于实现如下图所示的效果,其有关说法正确的是( )。

for (int i=1; i<6; i++) { // L1for (int j=1; j<i+1; j++) // L2cout << i*j << " ";cout << endl;
A.当前代码能实现预期效果,无需调整代码
B.如果cout<<endl; 移到循环L2内部, 则可实现预期效果
C.如果cout<<endl; 移到循环L1外部, 则可实现预期效果
D.删除cout<<endl; 行, 则可实现预期效果
【答案】:A
【解析】
当前代码能实现预期效果。
第14题
下面C++代码执行后,输出是( )。
int cnt1 = 0, cnt2 = 0;
fo r(int i=0; i<10; i++) {if (i % 2 == 0)continue;if (i % 2)cnt1 += 1;else if (i % 3 == 0)cnt2 += 1;
}
cout << cnt1 << " " << cnt2;
A.5 2
B.5 0
C.0 2
D.0 0
【答案】:B
【解析】
循环从i=0到i=9,共进行10次迭代。第一条if (i % 2 ==0)判断是否为偶数, 如果是则跳过当前循环(continue), 即只处理奇数值的i。对于每个奇数i, 第二条if(i % 2) 总是成立, 因为奇数对2取余不等于0, 所以cnt1将增加1。因此, else if (i % 3 == 0)永远不会被执行, 因为所有进入该分支的i都是奇数且已经通过了 if (i % 2)分支。
每一个奇数都会使cnt1增加1, 共有5个奇数(1, 3, 5, 7, 9) , 因此cnt1=5。cnt2在任何情况下都不会增加, 保持cnt2=0。
第15题
在下面的C++代码中,N必须是小于10大于1的整数,M为正整数(大于0)。如果M被N整除则M为幸运数,如果M中含有N且能被N整除,则为超级幸运数,否则不是幸运数。程序用于判断M是否为幸运数或超级幸运数或非幸运数。阅读下面代码,有关说法正确的是( )。
int N, M;
cout << "请输入幸运数字: ";
cin >> N;
cout << "请输入正整数: ";
cin >>M;bool Lucky;
if (M % N == 0)Lucky = true;
elseLucky = false;
while (M) {if (M % 10 == N && Lucky) {printf("%d是%d的超级幸运数!", M, N);break;}M /= 10;
}
if (M == 0)if (Lucky)printf("%d是%d的幸运数!", M, N);elseprintf("%d是%d的幸运数!", M, N);
A.如果N输入3,M输入36则将输出:36是3的超级幸运数!
B.如果N输入7,M输入21则将输出:21是7的幸运数!
C.如果N输入8,M输入36则将输出:36非8的超级幸运数!
D.如果N输入3,M输入63则将输出:63是3的超级幸运数!
【答案】:D
【解析】
随之while循环的进行, M会不断的除以10, 直至M变为0或M的个位等于N循环结束掉(break)。因此A选项输出时M为3, B选项输出时M为0,C选项输出时M为0,D选项正确。
判断题
第16题
执行C++代码 cout<<'9'+'1'; 的输出为10。( )
A.正确
B.错误
【答案】:B
【解析】
'9'和'1'是字符常量做算数运算时会被转换成int类型其值为ASCII码值,即57和49。因此'9'+'1'实际上是57+49,等于106,不是10。
第17题
C++表达式-12 % 10的值为2。( )
A.正确
B.错误
【答案】:B
【解析】
%运算符返回的是余数,-12%10的结果是-2。
第18题
C++表达式int(12.56) 的值为13。( )
A.正确
B.错误
【答案】:B
【解析】
int(12.56) 将浮点数12.56转换为整数, 方法为截断取整,即12。
第19题
C++的整型变量N被赋值为10, 则语句cout << N / 3 << "-" << N % 3执行后输出是3-1。( )
A.正确
B.错误
【答案】:A
【解析】
N=10;N / 3等于3(整数除法);N % 3等于1(取模运算);所以输出是3-1。
第20题
在C++代码中,不可以将变量命名为scanf, 因为scanf是C++语言的关键字。( )
A.正确
B.错误
【答案】:B
【解析】
scanf不是C++的关键字, 它是C标准库中的函数, 用于输入操作。因此在C++中, 可以将变量命名为scanf。
第21题
下面C++代码执行后将导致死循环。
for (int i=0; i<10; i++)continue;
A.正确
B.错误
【答案】:B
【解析】
continue语句只是跳过当前循环中的剩余部分并进入下一次迭代。因此,这个循环会正常结束,不会导致死循环。
第22题
下面C++代码执行后将输出10。( )
int cnt = 0;
for (int i=0; i<10; i++)for (int j=0; j<i; j++) {cnt += 1;break;}
cout << cnt;
A.正确
B.错误
【答案】:B
【解析】
外层循环从i=0到i=9,一共会执行10次。j的初值为0当j>i时会进入内层循环,因此i为(1,2,3...9)时会进入内层循环,共9次。在内层循环中会执行一次cnt自增并结束(break) , 因此cnt自增9次输出值为9。
第23题
下面C++代码执行后,将输出5。( )
int cnt = 0;
for (int i=1; i<5; i++)for (int j=1; j<5; j+=i)if (i * j % 2 == 0)cnt +=1;
cout << cnt;
A.正确
B.错误
【答案】:A
【解析】
外层循环从i=1到i=4,内层循环从j=i到j<5,每次增加i。
当i=1时,j为1,2,3,4,其中有2次i * j是2的倍数;
当i=2时,j为2,4,其中有2次i * j是2的倍数;
当i=3时,j为3;
当i=4时,j为4,其中有1次i * j是2的倍数;
总共自增5次, cnt最终值为5
第24题
下面C++代码能实现正整数各位数字之和。( )
int N,Sum = 0;
cin >> N;
while (N) {Sum += N % 10;N /= 10;
}
cout << Sum;
A.正确
B.错误
【答案】:A
【解析】
使用while循环, 当N不为0时, 执行以下操作:
用N % 10获取N的最后一位数字, 并将其加到Sum上。
用N /= 10去掉N的最后一位数字。
循环结束后, 输出Sum的值, 即输入整数各位数字之和。
第25题
GESP测试是对认证者的编程能力进行等级认证, 同一级别的能力基本上与编程语言无关。( )
A.正确
B.错误
【答案】:A
【解析】
同一级别不同语言所考察内容除语法细节外基本上相同。
编程题
B4002 平方之和
【题目来源】
洛谷:[B4002 GESP202406 二级] 平方之和 - 洛谷
【题目描述】
小杨有n个正整数\(a_1, a_2, \dots, a_n\), 他想知道对于所有的\(i(1\le i\le n)\) , 是否存在两个正整数\(x\)和\(y\)满足\(x\times x + y\times y=a_i\)。
【输入】
第一行包含一个正整数\(n\),代表正整数数量。
之后\(n\)行,每行包含一个正整数,代表\(a_i\)。
【输出】
对于每个正整数\(a_i\), 如果存在两个正整数\(x\)和\(y\)满足\(x\times x + y\times y=a_i\), 输出Yes, 否则输出No
【输入样例】
2
5
4
【输出样例】
Yes
No
【算法标签】
《洛谷 B4002 平方之和》 #循环结构# #GESP# #2024#
【代码详解】
#include <bits/stdc++.h>
using namespace std;// 判断一个数是否是完全平方数
bool check(int x)
{int y = sqrt(x); // 计算x的平方根,向下取整return y * y == x; // 检查y的平方是否等于x
}int main()
{int t; // 测试用例数量cin >> t;while (t--) { // 处理每个测试用例int n; // 输入的数字cin >> n;int fl = 0; // 标志位,0表示不满足,1表示满足// 遍历所有可能的i,使得i*i < nfor (int i = 1; i * i < n; i++) {int j = n - i * i; // 计算差值if (check(j)) { // 检查j是否是完全平方数fl = 1; // 如果j是完全平方数,设置标志break; // 找到就退出循环}}// 输出结果if (fl) cout << "Yes" << endl;else cout << "No" << endl;}return 0;
}
【运行结果】
2
5
Yes
4
No
B4007 计数
【题目来源】
洛谷:[B4007 GESP202406 二级] 计数 - 洛谷
【题目描述】
小杨认为自己的幸运数是正整数\(k\)(注:保证\(1\le k\le 9\))。小杨想知道,对于从\(1\)到\(n\)的所有正整数中,\(k\)出现了多少次。
【输入】
第一行包含一个正整数\(n\)。
第二行包含一个正整数\(k\)。
【输出】
输出从\(1\)到\(n\)的所有正整数中,\(k\)出现的次数。
【输入样例】
25
2
【输出样例】
9
【算法标签】
《洛谷 B4007 计数》 #循环结构# #GESP# #2024#
【代码详解】
#include <bits/stdc++.h>
using namespace std;// 计算数字x中数字y出现的次数
int check(int x, int y)
{int cnt = 0; // 计数器while (x > 0) { // 逐位检查x的每一位数字int tmp = x % 10; // 取出个位数if (tmp == y) { // 如果个位数等于ycnt++; // 计数器加1}x = x / 10; // 去掉个位数}return cnt; // 返回y在x中出现的次数
}int main()
{int n, k; // n: 范围上限, k: 目标数字cin >> n >> k; // 读取输入int ans = 0; // 总计数// 遍历1到n的所有数字for (int i = 1; i <= n; i++) {ans += check(i, k); // 计算数字i中k出现的次数,累加到总数}cout << ans << endl; // 输出结果return 0;
}
【运行结果】
25
2
9