内容正文:
CCF-GESP C++二级
CCF-GESP C++二级
编程能力等级认证
10道选择+3道编程
1
第十课
多层循环2
多层循环2
2
多层循环的应用
01
01
3
选择题
(2023年9月)以下C++代码实现从大到小的顺序输出N的所有因子,例如,输入N=18时,输出18 9 6 3 2 1,横线处应该填入( )。
C
int N=0;
cin>>N;
for(__________)//此处填写代码
if(!(N%i))
cout<<i<<' ';
;;
int i=1; i<N; i++
int i=N; i>0; i--
int i=N; i>1; i--
真题解析
本题正确的选项为C,详见下一页题目解析。
4
题目解析
int N=0;
cin>>N;
for(__________________) //此处填写代码
if(!(N%i))
cout<<i<<' ';
整数a除以整数b(b≠0) 的商正好是整数而没有余数,b就是a的因子。
输入N=18时输出18 9 6 3 2 1
18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1
i:
int i=N; i>0; i--
for( int i=18; i>0; i-- ){
//找出18的因子
}
真题解析
题目解析:
首先明确什么是因子,整数a除以整数b(b≠0) 的商正好是整数而没有余数,b就是a的因子。例如:18的因子有18,9,6,3,2,1,因子是从大到小输出。所以需要从18开始遍历一直到数字1,逐一找到18的因子。所以循环的范围就是18到1,循环的步伐是每次减1,因此在找出N的因子的时候,需要遍历N到1之间的所有整数,找出N的因子。所以循环的范围就是N到1,循环的步伐为每次减1。所以本题正确的选项为C。
5
选择题
(2023年9月)某班级人数不知,连续输入成绩直到输入负数停止,输入结束后求出平均成绩。在以下C++代码横线处应填入是( )。
true B. false C. True D. False
A
double totalScore=0; //总分
int studCount=0; //总人数
while(______){ //此处填写代码
cin>>score;
if(score<0)
break;
totalScore+=score;
studCount+=1;
}
cout<<"平均分="<<totalScore/studCount;
真题解析
解析:连续输入成绩直到输入负数停止,负数的布尔值是0,也就是False。那么循环条件的结果为true,执行循环体,循环条件为false,退出循环。因此本题正确的选项为A。
6
选择题
(2023年9月)下面C++代码执行后的输出是( )。
1 B. 3 C. 15 D. 没有输出
B
int cnt=0;
for(int i=1; i<13; i+=3)
for(int j=1; j<i; j+=2)
if(i*j%2==0)
break;
else
cnt+=1;
cout<<cnt;
真题解析
本题的正确选项为B,详见下一页题目解析。
7
题目解析
int cnt=0;
for(int i=1; i<13; i+=3)
for(int j=1; j<i; j+=2)
if(i*j%2==0)
break;
else
cnt+=1;
cout<<cnt;
i j i*j%2==0
1
4 1 当j=1,结果为true,执行break
7 1、3、5 当j=1,结果为false,执行cnt+=1
当j=3,结果为false,执行cnt+=1
当j=5,结果为false,执行cnt+=1
10 1 当j=1,结果为true,执行break
真题解析
题目解析:
这道题目需要注意内、外层循环的步伐。内层循环步伐为3,外层循环的步伐为2。根据外层循环的条件,循环变量i的取值为1,4,7,10。当i的值为1时,进入内层循环,j的值为1,内层循环条件为j<1,循环条件不成立,因此退出内层循环,回到外层循环中。执行i+=3,i的值4,进入内层循环,j=1,循环条件为j<4,循环条件成立,判断i*j%2==0这个条件是否成立,成立,则执行break,退出内层循环,回到外层循环,执行i+=3,i的值变为7,进入内层循环,j=1,判断循环条件j<7是否成立,成立,则继续判断i*j%2==0是否成立,不成立,则执行cnt+=1,之后令j+=2,j的值变为3,此时内层循环条件依然成立,
继续判断i*j%2==0是否成立,不成立,则执行cnt+=1,之后令j+=2,j的值变为5,此时内层循环条件依然成立,继续判断i*j%2==0是否成立,不成立,则执行cnt+=1,之后令j+=2,j的值变为7,此时内层循环条件不成立,退出内层循环,回到外层循环,令i+=3,i的值变为10,外层循环条件成立,进入内层循环,j=1,内层循环条件为j<10,循环条件成立,继续判断i*j%2==0是否成立,结果为true,执行break,退出内层循环,执行i+=3,i的值为13,此时循环条件不成立,所以退出外层循环。在整个执行过程中,cnt+=1,执行了3次,因此最终cnt的值为3。本题应该选择B。
8
选择题
(2023年9月)下面C++代码用于判断 N 是否为质数(素数),约定输入 N 为大于等于2的正整数,请在横线处填入合适的代码( )。
break
continue
exit
return
A
int N=0,i=0;
cout<<"请输入一个大于等于2的正整数:";
cin>>N;
for(i=2; i<N; i++)
if(N%i==0){
cout<<"非质数";
______________;//此处填写代码
}
if(i==N)
cout<<"是质数";
真题解析
解析:本题属于考察程序填空,根据题意,判断质数,质数的特点是只能被 1 和它本身整除,如果被 2~N-1 之间的数字整除,就不是质数,这样的数字找到 1 个,就不需要再循环判断了,因此填 break,本题正确的选项为A。
9
(2023年3月)百鸡问题🐔
【问题描述】
“百鸡问题”是出自我国古代《张丘建算经》的著名数学问题。大意为:“每 只公鸡 5 元,每只母鸡 3 元,每 3 只小鸡 1 元;现在有 100 元,买了 100 只鸡, 共有多少种方案?”
小明很喜欢这个故事,他决定对这个问题进行扩展,并使用编程解决:如果 每只公鸡 x 元,每只母鸡 y 元,每 z 只小鸡 1 元;
现在有 n 元,买了 m 只鸡,共有多少种方案?
【输入描述】
输入一行,包含五个整数,分别为问题描述中的 x、y、z、n、m。
约定 1≤ x, y, z ≤10,1≤ n, m ≤1000。
【输出描述】
输出一行,包含一个整数 C,表示有 C 种方案。
真题解析
10
【输入样例1】
5 3 3 100 100
【输出样例1】
4
【样例1解释】
这就是问题描述中的“百鸡问题”。
4 种方案分别为:公鸡 0 只、母鸡 25 只、 小鸡 75 只;
公鸡 4 只、母鸡 18 只、小鸡 78 只;
公鸡 8 只、母鸡 11 只、小鸡 81 只;
公鸡 12 只、母鸡 4 只、小鸡 84 只。
【输入样例2】
1 1 1 100 100
【输出样例2】
5151
(2023年3月)百鸡问题🐔
真题解析
解题思路:使用循环嵌套枚举公鸡和母鸡的数量,根据总价计算要求表示出小鸡数量,通过判断每种方案鸡的总数是否满足要求,从而统计出正确的方案数;
11
思路分析
列出题目给出信息:
鸡的价格:公鸡:x/只 ;母鸡:y/只;小鸡: z 只1元
手中钱数:n
购鸡总数:m
根据题目给出信息列出解题的条件:
公鸡数 ✖️ x ➕ 母鸡数 ✖️ y ➕ 小鸡数 ÷ z = n
公鸡数 ➕ 母鸡数 ➕ 小鸡数 = m
真题解析
12
思路分析
输入公鸡价格x,母鸡价格y,z只小鸡一元,总钱数n,购买鸡数m。
int x, y, z, n,m;
cin>>x>>y>>z>>n>>m;
真题解析
思路分析
公鸡数 ✖️ x ➕ 母鸡数 ✖️ y ➕ 小鸡数 ÷ z = n
公鸡数 ➕ 母鸡数 ➕ 小鸡数 = m
使用枚举法列出所有公鸡、母鸡可能的数量、计算小鸡数量。
0 1 2 3 4 .......
1) 列举公鸡数a的可能性
0 1 2 3 4 .......
2) 列举母鸡数b的可能性
for(int a=0; ____________________; a++){
}
for(int b=0; ___________________________; b++){
}
枚举公鸡数量(从0开始)
枚举母鸡数量(从0开始)
3) 根据已知条件计算小鸡数c (总钱数-买公鸡母鸡钱数)* z
a*x<=n 并且 a<=m
a*x+b*y<=n 并且 a+b<=m
a*x<=n&&a<=m
a*x+b*y<=n&&a+b<=m
int c=(n-a*x-b*y)*z;
计算小鸡数量
真题解析
14
思路分析
公鸡数 ✖️ x ➕ 母鸡数 ✖️ y ➕ 小鸡数 ÷ z = n
公鸡数 ➕ 母鸡数 ➕ 小鸡数 = m
统计符合条件的购买方案数量。
for(int a=0; a*x<=n&&a<=m; a++){
for(int b=0; a*x+b*y<=n&&a+b<=m; b++){
int c=(n-a*x-b*y)*z;
}
}
若满足以下条件,令购买方案数+1
公鸡数 ➕ 母鸡数 ➕ 小鸡数 = m
if(a+b+c==m) cnt++;
int cnt=0;
记录方案数量
真题解析
15
【完整代码】
#include <iostream>
using namespace std;
int main(){
int x,y,z,n,m;
cin>>x>>y>>z>>n>>m;
int cnt=0;
for(int a=0; a*x<=n&&a<=m; a++){
for(int b=0; a*x+b*y<=n&&a+b<=m; b++){
int c=(n-a*x-b*y)*z;
if(a+b+c==m) cnt++;
}
}
cout<<cnt<<endl;
return 0;
}
真题解析
完整代码
16
(2023年6月)找素数
【问题描述】
小明刚刚学习了素数的概念:如果一个大于 1 的正整数,除了 1 和它自身外,
不能被其他正整数整除,则这个正整数是素数。现在,小明想找到两个正整数A
和B之间(包括A和B)有多少个素数?
【输入描述】
输入 2 行,第一行包含正整数A,第二行包含正整数B。约定 2 ≤ A ≤ B ≤ 1000。
【输出描述】
输出一行,包含一个整数C,表示找到C个素数。
【输入样例1】
2
10
【输出样例2】
4
【输入样例1】
98
100
【输出样例2】
0
2 3 4 5 6 7 8 9 10
98 99 100
真题解析
17
思路分析
输入正整数a,正整数b。
int a = 0, b = 0;
cin >> a >> b;
创建变量cnt,统计素数个数。
int cnt = 0;
统计正整数 a 到 b 范围内的素数个数(包含a和b)。
for (int n = a; n <= b; n++){
//判断当前正整数n是否为素数
//累加素数的个数
}
真题解析
判断一个正整数是否为素数
素数:如果一个大于 1 的正整数,除了 1 和它自身外,不能被其他正整数整除,则这个正整数是素数。
例:判断9是否为素数
2 3 4 5 6 7 8
9 % 3 ->0
非素数
//判断n是否为素数
bool flag = true;
for (int i = 2; i < n; i++) {
if (n % i == 0) {
flag = false;
break;
}
}
先假设该数为素数
退出循环
真题解析
19
思路分析
统计正整数 a 到 b 范围内的素数个数(包含a和b)。
//遍历a~b之间所有的正整数
for (int n = a; n <= b; n++) {
//判断当前正整数n是否为素数
bool flag = true;
for (int i = 2; i < n; i++) {
if (n % i == 0) {
flag = false;
break;
}
}
if (flag) cnt++;
}
flag true 素数
flag false 非素数
根据flag的值累加素数的个数
输出素数的个数。
cout << cnt << endl;
真题解析
【完整代码】
#include <iostream>
using namespace std;
int main() {
int a = 0, b = 0, cnt = 0;
cin >> a >> b;
for (int n = a; n <= b; n++) {
bool flag = true;
for (int i = 2; i < n; i++) {
if (n % i == 0) {
flag = false;
break;
}
}
if (flag) cnt++;
}
cout << cnt << endl;
return 0;
}
真题解析
完整代码
21
(2023年3月)自幂数判断
【问题描述】
自幂数是指,一个N位数,满足各位数字N次方之和是本身。
例如:153 是 3 位数,其每位数的 3 次方之和,13 + 53 + 33 = 153,因此 153 是自幂数;1634 是 4 位数,其每位数的 4 次方之和,14 + 64 + 34 + 44 = 1634,因此 1634 是自幂数。
现在,输入若干个正整数,请判断它们是否是自幂数。
【输入描述】
输入第一行是一个正整数M,表示有M个待判断的正整数。约定 1 ≤ M ≤ 100。
从第 2 行开始的M行,每行一个待判断的正整数。约定这些正整数均小于108。
【输出描述】
输出M行,如果对应的待判断正整数为自幂数,则输出英文大写字母'T', 否则输出英文大写字母'F'。
【提示】
不需要等到所有输入结束在依次输出,可以输入一个数就判断一个数并输出,再输入下一个数。
真题解析
22
【输入样例1】
3
152
111
153
【输出样例1】
F
F
T
【输入样例2】
5
8208
548834
88593477
12345
5432
【输出样例2】
T
T
T
F
F
(2023年3月)自幂数判断
152 13 + 53 + 23 = 134
111 13 + 13 + 13 = 1
153 13 + 53 + 33 = 153
8208 84 + 24 + 04 + 84 = 8208
548834 56 + 46 + 86 + 86 + 36 + 46 = 548834
88593477 88 + 88 + 58 + 98 + 38 + 48 + 78 + 78 = 88593477
12345 15 + 25 + 35 + 45 + 55 = 4425
5432 54 + 44 + 34 + 24 = 978
真题解析
1+125+8=134
1+32+243+1024+3125=4425
625+256+81+16=978
23
思路分析
输入待判断整数的个数m。
int m = 0;
cin >> m;
输入m个数字,判断每个数字是否为自幂数。
int n = 0;
for (int i = 1; i <= m; i++) {
cin >> n;
}
1)计算当前正整数n是几位数
2)判断当前正整数n是否为自幂数
真题解析
24
思路分析
1)计算当前正整数n是几位数。
int t = n,
int l = 0;
while (t != 0) {
t /= 10;
l++;
}
2)判断当前正整数n是否为自幂数。
不改变n的值
记录位数
求自幂数的方式:
a:累加n的每位数的l次方
b:判断累加和是否与n相等
153 13 + 53 + 33 = 153
真题解析
解释int t=n; 在统计当前正整数n是几位数时,会改变n的值。由于后续需要判断累加和是否与n相等,因此需要n赋值给变量t,这样n值就不会改变了。
25
int sum = 0;
记录累加和
t = n; //t的值重置为n
while (t != 0){
}
int d = t % 10; //计算出每个数位上数字
t /= 10;
sum += pow(d, l);
if (sum == n)
cout << "T" << endl;
else
cout << "F" << endl;
2)判断当前正整数n是否为自幂数
求自幂数的方式:
a:累加n的每位数的l次方
b:判断累加和是否与n相等
思路分析
累加每位数的l次方
自幂数 T
非自幂数 F
真题解析
累加n的每位数的l次方,需要先对n进行数位分离,计算每个数位上的数字。
对未知位数的数字进行数位分离时,使用while循环,循环条件是t!=0,在循环当中,利用t%10可以计算出每个数位上的数字,讲计算结果保存到变量d中。之后再令t/=10,将原本的十位数变成个位数。继续求下一个数位上的数字...
之后可以累加每位数的l次方,如何求1个数字的l次方呢?可以使用pow函数,计算一个d的l次方,将计算的结果进行累加,保存到sum中。循环结束之后,sum中保存的就是n的每位数l次方的累加和。
最后将sum和n进行比较,如果sum和n相等,则为自幂数,输出T,否则,则为非自幂数,则输出F。
26
【完整代码】
#include <iostream>
#include <cmath>
using namespace std;
int main() {
int m = 0;
cin >> m;
for (int i = 1; i <= m; i++){
int n = 0;
cin >> n;
int t = n, l = 0;
while (t != 0) {
t /= 10;
l++;
}
int sum = 0;
t = n;
while (t != 0) {
int d = t % 10;
t /= 10;
sum += pow(d, l);
}
if (sum == n)
cout << "T" << endl;
else
cout << "F" << endl;
}
return 0;
}
提供pow函数
真题解析
完整代码
强调:代码中使用了pow函数,因此需要导入cmath头文件,这个头文件中提供了pow函数。
27
(2023年3月)百鸡问题🐔
【问题描述】
“百鸡问题”是出自我国古代《张丘建算经》的著名数学问题。大意为:“每 只公鸡 5 元,每只母鸡 3 元,每 3 只小鸡 1 元;现在有 100 元,买了 100 只鸡, 共有多少种方案?”
小明很喜欢这个故事,他决定对这个问题进行扩展,并使用编程解决:如果 每只公鸡 x 元,每只母鸡 y 元,每 z 只小鸡 1 元;
现在有 n 元,买了 m 只鸡,共有多少种方案?
【输入描述】
输入一行,包含五个整数,分别为问题描述中的 x、y、z、n、m。
约定 1≤ x, y, z ≤10,1≤ n, m ≤1000。
【输出描述】
输出一行,包含一个整数 C,表示有 C 种方案。
真题解析
百鸡问题的备用解法
28
【输入样例1】
5 3 3 100 100
【输出样例1】
4
【样例1解释】
这就是问题描述中的“百鸡问题”。
4 种方案分别为:公鸡 0 只、母鸡 25 只、 小鸡 75 只;
公鸡 4 只、母鸡 18 只、小鸡 78 只;
公鸡 8 只、母鸡 11 只、小鸡 81 只;
公鸡 12 只、母鸡 4 只、小鸡 84 只。
【输入样例2】
1 1 1 100 100
【输出样例2】
5151
(2023年3月)百鸡问题🐔
真题解析
解题思路:使用循环嵌套枚举公鸡和母鸡的数量,根据总价计算要求表示出小鸡数量,通过判断每种方案鸡的总数是否满足要求,从而统计出正确的方案数;
29
思路分析
列出题目给出信息。
鸡的价格:公鸡:x/只 ;母鸡:y/只;小鸡:z只1元
手中钱数:n
购鸡总数:m
根据题目给出信息列出解题的条件。
公鸡数 ✖️ x ➕ 母鸡数 ✖️ y ➕ 小鸡数 ÷ z = n
公鸡数 ➕ 母鸡数 ➕ 小鸡数 = m
使用枚举法列出所有公鸡、母鸡可能的数量。
0 1 2 3 …… n/x
公鸡最少0只,最多n/x只
母鸡最少0只,最多n/y只
0 1 2 3 …… n/y
利用条件求出小鸡数:(总钱数-买公鸡母鸡钱数)* z
真题解析
30
思路分析
输入公鸡价格x,母鸡价格y,z只小鸡一元,总钱数n,购买鸡数m。
int x, y, z, n, m;
cin>>x>>y>>z>>n>>m;
枚举公鸡、母鸡数量,计算小鸡数量,找出符合要求的购鸡方案数量。
for(int a=0; a<=n/x; a++){
for(int b=0; b<=n/y; b++){
int c=(n-a*x-b*y)*z;
}
}
枚举公鸡数量(0~n/x)
枚举母鸡数量(0~n/y)
公鸡数 ✖️ x ➕ 母鸡数 ✖️ y ➕ 小鸡数 ÷ z = n
公鸡数 ➕ 母鸡数 ➕ 小鸡数 = m
if(a+b+c==m) cnt++;
当满足如下条件,购鸡方案数量+1:
条件:公鸡数 ➕ 母鸡数 ➕ 小鸡数 = m
int cnt=0;
记录方案数量
计算小鸡数量
真题解析
31
思路分析
枚举公鸡、母鸡数量,计算小鸡数量,找出符合要求的购鸡方案数量。
0
1
2
3
0
1
2
3
保证公鸡、母鸡、小鸡的数量
大于等于0!!!
例如:公鸡1元/只,母鸡1元/只,小鸡1只1元,总钱数3,购鸡总数为3。
公鸡数
母鸡数
int cnt=0;
for(int a=0; a<=n/x; a++){
for(int b=0; b<=n/y; b++){
int c=(n-a*x-b*y)*z;
}
}
if(a+b+c==m&&a>=0&&b>=0&&c>=0) cnt++;
if(a+b+c==m) cnt++;
公鸡数 母鸡数 小鸡数
0 0 3
1 1 1
2 2 -1
3 3 -3
... ... ...
真题解析
32
【完整代码】
#include <iostream>
using namespace std;
int main() {
int x, y, z, n, m;
cin>>x>>y>>z>>n>>m;
int cnt=0;
for(int a=0; a<=n/x; a++){
for(int b=0; b<=n/y; b++){
int c=(n-a*x-b*y)*z;
if(a+b+c==m&&a>=0&&b>=0&&c>=0) cnt++;
}
}
cout<<cnt;
return 0;
}
真题解析
完整代码
33
感谢你的学习
34
$$