C++题目:母牛的故事

2020/6/21

  • 题目描述

    有一头母牛,它每年年初生一头小母牛。每头小母牛从第四个年头开始,每年年初也生一头小母牛。请编程实现在第n年的时候,共有多少头母牛?

  • 输入

    输入数据由多个测试实例组成,每个测试实例占一行,包括一个整数n(0<n<55),n的含义如题目中描述。
    n=0表示输入数据的结束,不做处理。

  • 输出

    对于每个测试实例,输出在第n年的时候母牛的数量。
    每个输出占一行。

  • 样例输入

    2
    4
    5
    0

  • 样例输出

    2
    4
    6

  • 要求

    时间限制: 1Sec 内存限制: 128MB

心路历程:

  • 通过列举第5、6、7年的母牛数6、9、13,想当然的以为母牛数cows = n + (n - 4) + (n - 3) + ... + 1,于是有:
#include<iostream>
using namespace std;

int sum1(int n) {
    int s = 0;
    for (int i = 1; i <= n; i++)
        s += i;
    return s;
}

int sum(int n) {
    if (n <= 4)
        return n;
    else
        return n + sum1(n - 4);
}

int main(){
    int n;
    while (cin >> n && n)
        cout << sum(n) << endl;
    return 0;
}

  • 被退回后发现算法过于头脑简单,因为没有考虑到小母牛所生的小母牛也有繁育能力,导致第8年以后的数据不再满足上述算法,需要在上述程序中引入函数递归的算法,可是思索许久,无从下手,于是查看解题思路,发现竟然有着很简单的隐藏函数关系!
    • 列举有:

      第n年 :1 2 3 4 5 6 7 8

      f(n)头牛:1 2 3 4 6 9 13 19

    • 得函数关系:

      • f(n) = f(n-1) + f(n-3) , n>=4;
      • f(1) = 1 , f(2) = 2 , f(3) = 3

于是有:

#include<iostream>
using namespace std;

int sum(int n) {
    if (n <= 3)
        return n;
    else
        return sum(n - 1) + sum(n - 3);
}

int main(){
    int n;
    while (cin >> n && n)
        cout << sum(n) << endl;
    return 0;
}

  • 提交后报错:时间超限。仔细思索,题目规定n<55,也就是说n最大可取54,由于函数的反复递归调用很费时间,当n超过50时,运行速度是极慢的(约5~20秒)。因此,不能够采用函数的方式进行递归,由于公式已得出,所以可以采用数组进行1-55递归数据的存储,由于只在主函数内作简单的算式递归,所以运行时间短到可以忽略不计。

最终答案:

#include<iostream>
using namespace std;

int main() {
    int n, i;
    int f[55] = { 0,1,2,3 };  //f[0]=0,f[1]=1,f[2]=2,f[3]=3
    for (i = 4; i < 55; i++)
        f[i] = f[i - 1] + f[i - 3];
    while (cin >> n && n)
        cout << f[n] << endl;
    return 0;
}

总结与收获:

    1. 一开始想当然的认为是简单的公式算法,没有列举更多的情况,也没有深入思考问题,以后需要细心全面看待问题;
    1. 一般采用递归算法的题目都能总结出相应的递归公式,且该递归公式往往不是能够直观反映问题的公式,例如此题中的f(n) = f(n-1) + f(n-3)是通过前几项的列举所直接推导出来的,因此利用递归算法解题时往往采取利用已知条件推导递归公式的方法;
    1. 递归算法不一定就是递归函数,当递归量很大时,采用函数的方式递归往往会使运行量变得极大,此时可以采用数组储存或进行新旧值的反复替换来完成高效率递归。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 第一部分:C++与C语言的差异(1-18) 1、C 和 C++ 中 struct 有什么区别? Protectio...
    程序爱好者阅读 2,135评论 0 2
  • 这些是C#和ASP.NET数据库面试题,全部从网上收集而来,经整理而发表,希望给大家带来帮助,有错误的地方还请各位...
    itming阅读 967评论 1 9
  • 1、用C语言实现一个revert函数,它的功能是将输入的字符串在原串上倒序后返回。 2、用C语言实现函数void ...
    希崽家的小哲阅读 6,720评论 0 12
  • 渐变的面目拼图要我怎么拼? 我是疲乏了还是投降了? 不是不允许自己坠落, 我没有滴水不进的保护膜。 就是害怕变得面...
    闷热当乘凉阅读 4,518评论 0 13
  • 感觉自己有点神经衰弱,总是觉得手机响了;屋外有人走过;每次妈妈不声不响的进房间突然跟我说话,我都会被吓得半死!一整...
    章鱼的拥抱阅读 2,431评论 4 5

友情链接更多精彩内容