GESP认证C++编程真题解析 | B3923 [GESP202312 二级] 小杨做题

​欢迎大家订阅我的专栏:算法题解:C++与Python实现
本专栏旨在帮助大家从基础到进阶 ,逐步提升编程能力,助力信息学竞赛备战!

专栏特色
1.经典算法练习:根据信息学竞赛大纲,精心挑选经典算法题目,提供清晰的代码实现与详细指导,帮助您夯实算法基础。
2.系统化学习路径:按照算法类别和难度分级,从基础到进阶,循序渐进,帮助您全面提升编程能力与算法思维。

适合人群:

  • 准备参加蓝桥杯、GESP、CSP-J、CSP-S等信息学竞赛的学生
  • 希望系统学习C++/Python编程的初学者
  • 想要提升算法与编程能力的编程爱好者

附上汇总帖:GESP认证C++编程真题解析 | 汇总


【题目来源】

洛谷:[B3923 GESP202312 二级] 小杨做题 - 洛谷

【题目描述】

为了准备考试,小杨每天都要做题。第 1 1 1 天,小杨做了 道题;第 2 2 2 天,小杨做了道题;从第 3 3 3 天起,小杨每天做的题目数量是前两天的总和。

此外,小杨还规定,当自己某一天做了大于或等于 m m m 题时,接下来的所有日子里,他就再也不做题了。

请问,到了第 N N N 天,小杨总共做了多少题呢?

【输入】

总共 4 4 4 行。第一行一个整数 a a a,第二行一个整数 b b b,第三行一个整数 m m m,第四行一个整数 N N N

【输出】

一行一个整数,表示小杨 N N N 天里总共做了多少题目。

【输入样例】

1
2
10
5

【输出样例】

19

【算法标签】

《洛谷 B3923 二级] 小杨做题》 #GESP# #2023#

【代码详解】

#include <bits/stdc++.h>  // 包含标准库头文件
const int N = 370;       // 定义数组最大长度
using namespace std;      // 使用标准命名空间

int m, n;    // m:阈值,n:项数
int a[N];    // 存储数列的数组

int main() {
    // 输入前两项和参数m,n
    cin >> a[1] >> a[2] >> m >> n;
    
    // 生成数列直到第n项或超过阈值m
    for (int i = 3; i <= n; i++) {
        a[i] = a[i-1] + a[i-2];  // 斐波那契数列规则
        if (a[i] >= m) {          // 如果超过阈值m
            n = i;                // 调整实际计算的项数
            break;               // 终止生成
        }
    }
    
    // 计算数列前n项的和
    int ans = 0;
    for (int i = 1; i <= n; i++) {
        ans += a[i];  // 累加每项
    }
    
    cout << ans << endl;  // 输出结果
    return 0;             // 程序正常结束
}

【运行结果】

1
2
10
5
19
<think>好的,我现在需要解决用户关于GESP202312二级考试中的小杨做题问题。首先,我需要仔细阅读用户提供的引用内容,理解题目要求和已有的代码结构。 根据引用[1]和[2],题目描述是:小杨第1天做a道题,第2天做b道题,从第3天开始,每天做题数是前两天之和。用户需要计算到第n天时总共做了多少题,或者当某一天的做题数超过m时提前输出并终止。引用[3]给出了一个C++代码示例,但看起来可能存在逻辑错误,比如变量s的使用可能有问题。 接下来,我需要分析问题。题目要求每天做题的数量遵循类似斐波那契数列的规律,但总和的计算方式需要注意。例如,前三天分别是a, b, a+b,总题数应该是a + b + (a+b) = a + b + a + b = 2a + 2b?还是每天累计总和?需要明确题目是求总题数还是每天题数的总和。根据代码中的循环,s被累加为a + b,然后在循环中不断更新a和b的值,这可能存在问题。例如,初始的s在第一天和第二天应该是a和b的总和,但循环从i=1到n,可能在第一天就累加了a和b,导致结果错误。 可能需要重新梳理逻辑。正确的做法应该是每天计算当天的题数,并累加到总和中。例如,第1天总题数是a,第2天是a+b,第3天是a+b + (a+b)=2a+2b,然后第3天的题数是前两天的和,即a + b。这里可能存在混淆,到底是求到第n天的总题数,还是每天题数的总和。根据代码中的s = s + a + b,可能在循环中将a和b相加,但这样可能在循环开始时就将第1天和第2天的题数重复计算。 例如,假设n=2,输入a=1,b=2,那么循环执行两次。第一次i=1,s +=1+2=3,此时总题数应该是第1天和第2天的总和,即3,正确。但如果n=3,第三次循环i=3,s会再加上新的a和b,但此时a和b已经被更新为前一次的值,可能不正确。 因此,代码中的逻辑可能有误,正确的做法应该是维护一个当前天数的题数,而不是直接累加a和b。可能需要使用变量来记录前两天的题数,并逐天计算。 接下来,我需要根据正确的逻辑重新编写代码,并解释每一步的作用。同时,考虑到题目可能要求当某一天的题数超过m时立即输出并终止,这需要在循环中加入条件判断。 最后,生成相关问题,帮助用户进一步理解和巩固相关知识,比如递推数列的应用、循环结构的使用以及边界条件的处理等。</think>### GESP202312二级考试:小杨做题问题解析 #### 题目要求梳理 1. **输入参数**:$a$(第1天题数)、$b$(第2天题数)、$m$(阈值)、$n$(总天数) 2. **规则**: - 第3天起,每天题数是前两天的总和。 - **总题数**需要累加到第$n$天。 - 若某天的题数超过$m$,则**立即输出该值并终止程序**。 3. **输出**:最终总题数或首次超过$m$的值[^1][^2]。 --- #### 代码分析与修正 引用[3]提供的代码存在逻辑错误: ```cpp for (int i =1; i<=n; i++) { s = s +a +b; // 错误:直接将a+b累加,但a和b已被更新 a = b; // 导致后续天数计算不准确 b = s; } ``` **修正后的逻辑**: 1. **变量设计**: - `total`:累计总题数(初始为$a + b$) - `prev1`:记录前一天题数(初始为$a$) - `prev2`:记录前两天题数(初始为$b$) 2. **递推过程**: - 从第3天开始,每天题数=`prev1 + prev2` - 更新`prev1`和`prev2`的值 --- #### 正确代码实现(C++) ```cpp #include <iostream> using namespace std; int main() { int a, b, m, n; cin >> a >> b >> m >> n; if (n == 1) { cout << a << endl; return 0; } int total = a + b; int prev1 = a, prev2 = b; for (int day = 3; day <= n; day++) { int current = prev1 + prev2; total += current; if (current > m) { cout << current << endl; return 0; } prev1 = prev2; prev2 = current; } cout << total << endl; return 0; } ``` **代码说明**: - **边界处理**:当$n=1$时直接输出$a$ - **循环逻辑**:从第3天开始递推,逐日计算题数 - **终止条件**:若某天题数超过$m$,立即输出并结束 --- #### 关键知识点 1. **递推数列**:类似斐波那契数列的生成方式[^1] 2. **循环控制**:`for`循环的边界与变量更新 3. **条件判断**:阈值检测与提前终止 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值