题目来源:2023 年 12 月 CCF GESP C++ 二级 编程题 第一题 小杨做题
1 题目:小杨做题
题目描述:
为了准备考试,小杨每天都要做题。
第 1 天,小杨做了 1 道题;第 2 天,小杨做了 2 道题;从第 3 天起,小杨每天做的题目数量是前两天的总和。
此外,小杨还规定,当自己某一天做了大于或等于 m 题时,接下来的所有日子里,他就再也不做题了。
请问,到了第 N 天,小杨总共做了多少题呢?
输入:
总共 4 行。第一行一个整数 a,第二行一个整数 b,第三行一个整数 m,第四行一个整数 N。
保证 0 < = a , b < = 10 0<=a,b<=10 0<=a,b<=10 ; a , b < M < = 1000000 a,b<M<=1000000 a,b<M<=1000000 ; 3 < = N < = 364 3<=N<=364 3<=N<=364 。
输出:
一行一个整数,表示小杨 N 天里共做了多少题目。
特别提醒:
在常规程序中,输入、输出时提供提示是好习惯。但在本场考试中,由于系统限定,请不要在输入、输出中附带任何提示信息。
样例输入 1:
1
2
10
5
样例输出 1:
19
样例解释 1:
小杨第一天做 1 题,第二天做 2 题,第三天做 1+2=3 题,第四天做 2+3=5 题,第五天做 3+5=8 题。因此他总共做了 1+2+3+5+8=19 题。
样例输入 2:
1
1
5
8
样例输出 2:
12
样例解释 2:
小杨前 5 天分别做了 1,1,2,3,5 题,由于第 5 天小杨做了 5 题,而 m=5 ,于是小杨从此以后不再做题。因此小杨总共做了 1+1+2+3+5=12 题。
2 题目分析
第一步,完成输入部分,根据要求,输入总共 4 个数。
第 1 个整数 a,第 2 个整数 b,第 3 个整数 m,第 4 个整数 N。
并且所有的数据范围
0
<
=
a
,
b
<
=
10
0<=a,b<=10
0<=a,b<=10 ;
a
,
b
<
M
<
=
1000000
a,b<M<=1000000
a,b<M<=1000000 ;
3
<
=
N
<
=
364
3<=N<=364
3<=N<=364 ,都在 int 范围内。
int a,b,m,N;
cin>>a>>b>>m>>N;
输入部分完成!
接下来,分析题目意思,小杨的做题数量为:
第 1 天,做了 1 道题;第 2 天,做了 2 道题;从第 3 天起,每天做的题目数量是前两天的总和。
这个和斐波那契数列非常像,代入输入的变量,转换为:第 1 天,做 a 题,第 2 天,做 b 题,第 3 天,做 a+b 题,第 4 天,做 b+a+b 题,以此类推。
可以得出以下规律:
![[Pasted image 20231220100939.png]]
但是这样的规律看起来太复杂了,可以用一个新的变量来替代第三天。
![[Pasted image 20231220101316.png]]
接着在继续用一个新的变量来代替第四天,以此类推。
int c=a+b;//a代替第一天,b代替第二天,c代替第三天
a=b;//要计算第四天时,第二天,变成第一天
b=c;//第三天,变成第二天
接着要进行 N 天,由于前面两天已经知道,因此循环从第 3 天开始。
for(int i=3;i<=N;i++)
{
}
结合在一起。
for(int i=3;i<=N;i++)
{
int c=a+b;//a代替第一天,b代替第二天,c代替第三天
a=b;//要计算第四天时,第二天,变成第一天
b=c;//第三天,变成第二天
}
完成之后,可以代入数据验证一下,查看结果是否符合要求。
#include<iostream>
using namespace std;
int main()
{
int a,b,m,N;
cin>>a>>b>>m>>N;
int c=0;
for(int i=3;i<=N;i++)
{
c=a+b;//a代替第一天,b代替第二天,c代替第三天
a=b;//要计算第四天时,第二天,变成第一天
b=c;//第三天,变成第二天
}
cout<<c;
return 0;
}
可以用样例输入 1 进行验证,发现输出 8,刚好是第 5 天所做的题,因此该写法正确!
![[Pasted image 20231220102446.png]]
但这不是最终答案,要求输出的是总题目数。所以需要一个累加器。
int ans=0;//累加器,初始值为0
但由于循环是从 3 开始,因此需要将前两天的和加入到累加器中。
ans=a+b;
再将累加器放入到循环中,对数据进行累加。
int ans=a+b;
for(int i=3;i<=N;i++)
{
int c=a+b;//a代替第一天,b代替第二天,c代替第三天
a=b;//要计算第四天时,第二天,变成第一天
b=c;//第三天,变成第二天
ans+=c;//进行累加
}
题目中还有一个限制,就是当小杨某一天做了大于或等于 m 题时,接下来的所有日子里,他就再也不做题了。
所以需要进行限制,即 c 变量遇到大于等于 m 时,跳出整个循环。
int ans=a+b;
for(int i=3;i<=N;i++)
{
int c=a+b;//a代替第一天,b代替第二天,c代替第三天
a=b;//要计算第四天时,第二天,变成第一天
b=c;//第三天,变成第二天
ans+=c;//进行累加
if(c>=m) break;
}
以上,即完成整个程序逻辑,最后加上输出即可!
3 参考代码
#include<iostream>
using namespace std;
int main()
{
int a,b,m,N;
cin>>a>>b>>m>>N;
int ans=a+b;
for(int i=3;i<=N;i++)
{
int c=a+b;//a代替第一天,b代替第二天,c代替第三天
a=b;//要计算第四天时,第二天,变成第一天
b=c;//第三天,变成第二天
ans+=c;//进行累加
if(c>=m) break;
}
cout<<ans;
return 0;
}