内容正文:
CCF-GESP C++二级
CCF-GESP C++二级
编程能力等级认证
1
循环与分支
循环与分支
第八课
2
循环与分支
01
01
3
选择题
(2023年3月)执行以下C++语言程序后,输出结果是( )。
#include <iostream>
using namespace std;
int main(){
int n=17;
bool isprime=true;
for(int i=2;i<=n;i++)
if(n%i==0)
isprime=false;
cout<<isprime<<endl;
return 0;
}
C
false
true
0
1
真题解析
本题正确选项为C,详见下一页题目解析。
4
题目解析
int n=17;
bool isprime=true;
for(int i=2;i<=n;i++)
if(n%i==0)
isprime=false;
cout<<isprime<<endl;
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
i
17%i==0
17%i==0 成立
isprime=false;
执行程序输出结果:0
真题解析
题目解析:
循环变量i的初始值为2,循环条件为i<=n,即i<=17,循环步伐为i++,因此i的取值为2~17.
循环中判断n%i==0是否成立,即17%i==0是否成立。
当i的取值为17时,n%i==0成立,执行isprime=false;
输出isprime的值应该是0。
5
选择题
(2023年6月)在下列代码的横线处填写( ),可以使输出是42。
#include <iostream>
using namespace std;
int main(){
int sum=0;
for(int i=1; i<=20; i++)
if(___________)
sum+=i;
cout<<sum<<endl;
return 0;
}
i%3==0
20%i==0
i<=8
i>=18
B
真题解析
本题正确选项为B,详见下一页题目解析。
6
题目解析
i%3==0
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
i
B. 20%i==0
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
i
C. i<=8
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
i
D. i>=18
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
i
求和结果:63
求和结果:42
求和结果:36
求和结果:57
真题解析
解析:循环变量从1开始,循环条件为i<=20,循环步伐为i++。因此循环变量i的范围是1~20
循环中,当if语句的条件成立,则累加i的值。目前已知最终的累加和为42。
若if语句中的条件为选项A,i%3==0,则当i为3的倍数时,进行累加操作,即累加3,6,9,12,15,18求和,最终求和结果为63
若if语句中的条件为选项B,20%i==0,则当i为20的因子时,进行累加操作,即累加1,2,4,5,10,20,求和,最终求和结果为42
因此正确选项为B。
7
(2023年6月)执行以下C++语言程序后,输出结果是( )。
选择题
C
#include <iostream>
using namespace std;
int main(){
for(char x='A'; x<='D'; x++){
if((x!='A')+(x=='C')+(x=='D')+(x!='D')==3)
cout<<x;
}
return 0;
}
A B. B C. C D. D
真题解析
本题正确选项为C,详见下一页题目解析。
8
题目解析
x='A'
判断条件:(x!='A')+(x=='C')+(x=='D')+(x!='D')==3
x='B'
判断条件:(x!='A')+(x=='C')+(x=='D')+(x!='D')==3
0
0
0
1
1
0
0
1
x='C'
判断条件:(x!='A')+(x=='C')+(x=='D')+(x!='D')==3
1
1
0
1
x='D'
判断条件:(x!='A')+(x=='C')+(x=='D')+(x!='D')==3
1
0
1
0
真题解析
题目解析:
当x为‘A’ 时,x!='A'的结果为0,x=='C'的结果为0,x=='D'结果为0,x!='D'的结果为1。相加的结果为1,因此if语句的条件不成立
当x为‘B’时,x!='A'的结果为1,x=='C'的结果为0,x=='D'结果为0,x!='D'的结果为1。相加的结果为2,因此if语句的条件不成立
当x为‘C’时,x!='A'的结果为1,x=='C'的结果为1,x=='D'结果为0,x!='D'的结果为1。相加的结果为3。if语句的条件成立,
最终输出x的值为‘C’。
9
选择题
(2023年9月)下列流程图的输出结果是?( )
5 12
12 5
5 5
12 12
B
开始
x>y
是
否
a=x
b=y
a=y
b=x
结束
x=5, y=12
输出a,b
真题解析
解析:该流程图描述的是选择结构:x和y的初始值分别是5和12,判断x>y是否成立,该条件不成立,执行a=y,b=x,则a的值为12,b的值为5。最终输出的结果为12 5
10
选择题
#include <iostream>
using namespace std;
int main(){
int N=9;
for(int i=2; i<N; i++)
if(N%i)
cout<<"1#";
cout<<"0"<<endl;
return 0;
}
(2023年9月)下面C++代码执行后的输出是( )
D
1#0
1#
1#1#1#1#1#1
1#1#1#1#1#1#0
真题解析
本题正确选项为D,详见下一页题目解析。
11
题目解析
i N%i的结果 输出
2 True 1#
3 False
4 True 1#
5 True 1#
6 True 1#
7 True 1#
8 False 1#
#include <iostream>
using namespace std;
int main(){
int N=9;
for(int i=2; i<N; i++)
if(N%i)
cout<<"1#";
cout<<"0"<<endl;
return 0;
}
循环结束
程序输出的结果为:1#1#1#1#1#1#0
真题解析
题目解析:
循环变量i的初始值为2,循环条件为i<N,即i<9,循环步伐为i++,i的取值为2~8。
循环中if语句的条件为N%i的结果,N为9,即9%i的结果。
当i值为2,4,5,6,7,8时,判断条件9%i的结果均为1,会执行6次输出语句,输出6遍“1#”
程序最后输出“0”,因此代码执行后输出的结果是1#1#1#1#1#1#0
12
int x=1;
while(x<100){
if(!(x%3))
cout<<x<<",";
else if(x/10)
break;
x+=2;
}
cout<<x;
选择题
(2023年9月)下面C++代码执行后的输出是( )
B
1
3,9,11
3,6,9,10
1,5,7,11,13,15
真题解析
本题正确选项为B,详见下一页题目解析。
13
题目解析
int x=1;
while(x<100){
if(!(x%3))
cout<<x<<",";
else if(x/10)
break;
x+=2;
}
cout<<x;
x !(x%3)的结果 x/10的结果 x+=2
1 False False x->3
3 True 输出:3, False x->5
5 False False x->7
7 False False x->9
9 True 输出:9, False x->11
11 False True 循环结束
程序输出的结果为:3,9,11
真题解析
题目解析:
x=1,!(x%3)的结果为0,不输出当前x的值,继续判断x/10的结果为0,执行x+=2,x的值变为3
x=3,!(x%3)的结果为1,输出x的值和逗号,继续判断x/10的结果为0,执行x+=2,x的值变为5
x=5,!(x%3)的结果为0,不输出当前x的值,继续判断x/10的结果为0,执行x+=2,x的值变为7
x=7,!(x%3)的结果为0,不输出当前x的值,继续判断x/10的结果为0,执行x+=2,x的值变为9
x=9,!(x%3)的结果为0,输出x的值和逗号,继续判断x/10的结果为0,执行x+=2,x的值变为11
x=11,!(x%3)的结果为0,不输出当前x的值,继续判断x/10的结果为1,执行break语句,此时循环结束,最终输出x的值为11.
因此程序输出的结果为:3,9,11
14
选择题
(2023年12月)下面C++代码执行后的输出是( )
C
int N=100;
while(N>0){
if(N%2)
break;
else if(N%3==0)
N-=5;
else
N-=20;
}
cout<<N;
100
95
55
0
真题解析
本题正确选项为C,详见下一页题目解析。
15
选择题
N N%2 N%3==0 执行语句
100 False False N-=20
80 False False N-=20
60 False True N-=5
55 True 循环结束
int N=100;
while(N>0){
if(N%2)
break;
else if(N%3==0)
N-=5;
else
N-=20;
}
cout<<N;
真题解析
(2023年9月)数字黑洞
【问题描述】
给定一个三位数,要求各位不能相同。例如:352是符合要求的, 112是不符合要求的。将这个三位数的三个数字重新排列,得到的最大的数,减去得到的最小的数,形成一个新的三位数。对这个新的三位数可以重复上述过程。神奇的是,最终一定会得到495!
试试看,重新排列352,得到的最大数为532,最小数为235,它们的差是297;变换297,得到972-279=693;变换693,963-369=594;变换594,954-459=495。因此,352经过4次变换得到了495。 现在,输入的三位数,你能通过编程得出,这个三位数经过多少次变换能够得到495吗?
【输入描述】
输入一行,包含一个符合要求的三位数N。
【输出描述】
输出一行,包含一个整数C ,表示经过C次变换得到495。
【输入样例】
352
【输出样例】
4
真题解析
解释变换过程
17
思路分析
输入一个三位数n。
int n;
cin >> n;
计算三位数经过多少次变换能够得到495。
int t=0; //记录变换次数
while( ){
t++;
}
n!=495
1)变换数字n
2)将下一个要变换的数赋值给n
当n为495时
停止变换
真题解析
解题过程:
1、首先输入一个三位整数n
2、之后再来计算三位数需要经过多少次变换能够得到495。
这里需要使用一个变量t记录变换次数
然后使用循环来统计变换次数,变换得到495的次数是不确定的,因此可以使用while循环来解决这个问题。再
在while循环中,需要变换数字n,再将下一个要变换的数值赋值给n,我们令变量n中始终保存的要变换的数字。
每次变换完成之后都进行计数,令t++;
思考:循环的条件是什么呢?根据题目要求,当n的值为495的时候就停止变换,因此循环条件为n!=495。
如何实现变换数字n呢?
18
如何变换一个数?
例:重新排列352,得到的最大数为532,最小数为235,它们的差是297
数位分离
个位:352%10
十位:352/10%10
百位:352/100
2
5
3
对分离出的数重新排列,计算最大数和最小数
最大
次大
最小
最大数:5*100+3*10+2
最小数:2*100+3*10+5
532
235
将最大数和最小数的差作为下一个要变换的数
最大数-最小数:532-235
297
真题解析
分析如何变换一个数:
以重新排列352为例,得到的最大数为532,最小数为235,它们的差是297
1、要组成最大数和最小数,先进行数位分离:
个位:352%10
十位:352/10%10
百位:352/100
2、之后对分离出的数重新排列,计算最大数和最小数
组成最大最小数时,要明确分离出来的数字中,哪个是最大的,次大的,和最小的
计算最大数时:需要使用最大值*100+次大值*10+最小值
计算最小数时:需要使用最小值*100+次大值*10+最大值
3、计算出最大和最小值之后,将最大数和最小数的差作为下一个要变换的数
19
实现变换一个数n
数位分离(a:个位,b:十位,c:百位)。
int a = n % 10;
int b = n / 10 % 10;
int c= n / 100;
对分离出的数重新排列,计算最大数和最小数。
1) 找出a,b,c中的最大、次大、最小数
a记录最小数,b记录次大数,c记录最大数
a
b
c
a和b比
if(a>b){
// a和b交换
}
if(a>c){
// a和c交换
}
a
b
c
a和c比
if(b>c){
// b和c交换
}
a
b
c
b和c比
真题解析
代码实现变换一个数n的过程:
1、进行数位分离,使用三个变量分别保存每一位上的数,a:个位,b:十位,c:百位
int a = n % 10;
int b = n / 10 % 10;
int c= n / 100;
2、对分离出的数重新排列,计算最大数和最小数
这里需要先找出a,b,c中的最大、次大、最小数
查找过程中,我们可以使用a记录最小数,b记录次大数,c记录最大数
如何查找呢?
首先可以让a和b比较,如果a大于b,则令a和b交换
之后可以让a和c比较,如果a大于c,则令a和c交换,此时a中保存的就是最小数了
最后可以让b和c比较,如果b大于c,则令b和c交换,此时c中保存的就是最大数,b中保存的就是次大数了。
20
实现变换一个数n
对分离出的数重新排列,计算最大数和最小数。
if(a>b) swap(a,b);
if(a>c) swap(a,c);
if(b>c) swap(b,c);
1) 找出a,b,c中的最大、次大、最小数
a记录最小数,b记录次大数,c记录最大数
2) 计算最大数、最小数
int tmax=c*100+b*10+a;
int tmin=a*100+b*10+c;
将最大数和最小数的差作为下一个要变换的数。
n=tmax-tmin;
真题解析
这一步骤代码实现:
可以直接使用swap函数交换两个变量的值。
如果a>b, 交换a和b的值
如果a>c,交换a和c的值
如果b>c,交换b和c的值
然后来计算最大数、最小数,可以创建两个变量tmax和tmin分别保存最大数和最小数。
tmax=c*100+b*10+a;
tmin=a*100+b*10+c;
将最大数和最小数的差作为下一个要变换的数,这个数可以重新赋值给变量n
这样变量n中始终保存的是要被变换的数。
21
思路分析
while(n!=495){
int a=n%10, b=n/10%10, c=n/100;
if(a>b) swap(a,b);
if(a>c) swap(a,c);
if(b>c) swap(b,c);
int tmax=c*100+b*10+a;
int tmin=a*100+b*10+c;
n=tmax-tmin;
t++;
}
计算三位数经过多少次变换能够得到495。
输出变换次数。
cout<<t;
真题解析
现在展示的是第二步的完整代码,计算完成之后。
最终需要输出变换次数。也就是输出t的值。
22
【完整代码】
#include <bits/stdc++.h> using namespace std;
int main() {
int n;
cin >> n;
int t=0;
while(n!=495){
int a=n%10, b=n/10%10, c=n/100;
if(a>b) swap(a,b);
if(a>c) swap(a,c);
if(b>c) swap(b,c);
int tmax=c*100+b*10+a;
int tmin=a*100+b*10+c;
n=tmax-tmin;
t++;
}
cout<<t;
return 0;
}
真题解析
公交卡充值问题
【问题描述】
小明去公交卡充值中心为自己的公交卡充值,公交充值中心搞了一个充值优惠活动,活动详情如下: (1)充值200元~299元,赠送50元余额到卡中;
(2)充值300元~499元,赠送100元余额到卡中;
(3)充值500元及500元以上,赠送200元余额到卡中;
(4)充值200元以下,没有赠送活动;
例如:小明如果充值350元,那么实际卡中到账的金额将会是450元(350元充值 + 100元赠送)。 请编程帮助公交卡充值中心,根据客户的充值金额,计算实际应当到账的金额。
【输入描述】
一个正整数n,代表充值金额(n是1~999之间的整数)。
【输出描述】
一个正整数,代表实际到账的金额。
【输入样例】
200
【输出样例】
250
课堂练习
此处需要强调小明如果充值350元,那么实际卡中到账的金额将会是450元,实际到账金额=充值金额+赠送金额。
24
思路分析
输入充值金额n。(1≤n≤999)
根据客户的充值金额,计算实际应当到账的金额。
int n;
cin>>n;
充值规则:
200元~299元,赠送50元;
300元~499元,赠送100元;
500元及500元以上,赠送200元;
200元以下,没有赠送活动;
if(n>=200 && n<300){
cout<<n+50;
}
else if(n>=300 && n<500 ){
cout<<n+100;
}
else if(n>=500){
cout<<n+200;
}
else {
cout<<n;
}
实际到账金额=充值金额+赠送金额
课堂练习
解题思路:
1、首先输入充值金额,保存至一个整型变量n中
2、再根据客户的充值金额,计算实际应当到账的金额,充值规则如下:
200元~299元,赠送50元;
300元~499元,赠送100元;
500元及500元以上,赠送200元;
200元以下,则没有赠送活动;
注意:计算实际到账金额=充值金额+赠送金额
可以使用if else if分支语句,对不同的充值金额进行判断。
充值规则共有4条,对应4条分支语句。
如果n>=200 && n<300,则令n+5,结果为实际到账金额,使用cout语句直接输出。
否则如果n>=300 && n<499,输出n+100的结果,
否则如果n>=500,输出n+200的结果,
否则,输出n的结果。
25
【完整代码】
#include <iostream>
using namespace std;
int main(){
int n;
cin>>n;
if(n>=200&&n<300){
cout<<n+50;
}
else if(n>=300&&n<500){
cout<<n+100;
}
else if(n>=500){
cout<<n+200;
}
else {
cout<<n;
}
return 0;
}
课堂练习
完整代码
26
足球联赛积分
【问题描述】
一场比赛中,两支参赛队A,B。如果A队的进球数大于B队,则A赢,A积3分,B积0分。如果A队的进球数等于B队,则两队打平,各积1分。如果A队的进球数小于B队,则A输,A积分0分,B积分3分。
【输入描述】
第一行,一个正整数n,代表比赛场数(1≤n≤40)。
接下来n行,每行两个整数,数字之间使用一个空格隔开,表示一场该球队的进球数以及对手球队的进球数。(输入整数的范围:0~10)
【输出描述】
一个整数,表示该球队的赛季积分。
【输入样例】
5
3 1
0 0
1 2
3 2
3 3
【输出样例】
8
【提示】
该球队5场比赛的结果分别为赢,平,输,赢,平,总计2赢2平1输,积分为8分。
课堂练习
1、介绍比赛积分的规则:如果A队的进球数大于B队,则A赢,A积3分,B积0分。如果A队的进球数等于B队,则两队打平,各积1分。如果A队的进球数小于B队,则A输,A积分0分,B积分3分。
2、最终只需要计算我方球队的赛季积分。
27
思路分析
【输入样例】
5
3 1
0 0
1 2
3 2
3 3
【输出样例】
8
比赛积分规则:
A队的进球数大于B队,A队积3分,B积0分。
A队的进球数等于B队,A队积1分,B积1分。
A队的进球数小于B队,A队积0分,B积3分。
每场进球数
我
方
球
队
对
方
球
队
我方球队
赛季积分
我方积分+3
我方积分+1
我方积分+0
我方积分+3
我方积分+1
课堂练习
解释样例数据:
第一个数据5,为比赛的场数。之后的每行数据为每场两队的进球数,第一列为我方球队的每场进球数,第二列为对方球队的每场进球数。
最终要输出的是我方球队本赛季的积分。
首先明确比赛积分规则:
1)A队的进球数大于B队,A队积3分,B积0分。
2)A队的进球数等于B队,A队积1分,B积1分。
3)A队的进球数小于B队,A队积0分,B积3分。
根据比赛积分规则,可以计算出5场比赛,每一场我方球队的积分。
第一场比赛我方进球3个,对方进球1个,我方大于对方,因此我方积分+3。
第二场比赛我方进球0个,对方进球0个,我方等于对方,因此我方积分+1。
第三场比赛我方进球1个,对方进球2个,我方小于对方,因此我方不积分。
第四场比赛我方进球3个,对方进球2个,我方大于对方,因此我方积分+3。
第五场比赛我方进球3个,对方进球3个,我方等于对方,因此我方积分+1。
我方总积分为8,因此最终输出数值8。
28
int x,y; //x:我方,y:对方
for(int i=1;i<=n;i++){
cin>>x>>y;
}
int x,y; //x:我方,y:对方
for(int i=1;i<=n;i++){
cin>>x>>y;
}
思路分析
输入比赛场数n。(1≤n≤40)
输入n场比赛的两队的进球数,同时计算我方球队的总积分。
int n;
cin>>n;
比赛规则:
A队的进球数大于B队,A队积3分,B积0分。
A队的进球数等于B队,A队积1分,B积1分。
A队的进球数小于B队,A队积0分,B积3分。
int sum=0;
记录我方球队赛季总积分
if(x>y){
sum+=3;
}else if(x==y){
sum+=1;
}else{
sum+=0;
}
可以省略
if(x>y){
sum+=3;
}else if(x==y){
sum+=1;
}
输出我方球队的赛季总积分。
cout<<sum;
课堂练习
代码实现:
1、首先输入比赛场数n
2、输入n场比赛的两队的进球数,计算我方球队的总积分。
1)创建变量x和y分别记录我方和对方球队的进球数
之后循环n次,输入我方和对方球队的进球数,可以边输入的同时边计算我方球队的总积分。
2)需要先创建一个变量sum用于记录我方球队本赛季积分,变量需要初始化为0。
比赛规则有3条:因此可以使用if else if分支语句进行判断
如果x>y成立,则我方球队积3分,令sum+=3;
否则如果x==y成立,则我方球队积1分,令sum+=1;
否则,我方球队积0分,令sum+=0;
其中else分支语句可以省略,因此只需要两条分支即可。
3、输出我方球队的赛季总积分
29
【完整代码】
#include<iostream>
using namespace std;
int main(){
int n;
cin>>n;
int x,y;
int sum=0;
for(int i=1;i<=n;i++){
cin>>x>>y;
if(x>y){
sum+=3;
}else if(x==y){
sum+=1;
}
}
cout<<sum;
return 0;
}
课堂练习
完整代码
30
感谢你的学习
31
$$