C/C++查漏补缺——一个递归的例子

来源:https://www.dotcpp.com/oj/problem1004.html

题目 1004: [递归]母牛的故事

时间限制: 1Sec 内存限制: 128MB
题目描述
有一头母牛,它每年年初生一头小母牛。每头小母牛从第四个年头开始,每年年初也生一头小母牛。请编程实现在第n年的时候,共有多少头母牛?
输入
输入数据由多个测试实例组成,每个测试实例占一行,包括一个整数n(0<n<55),n的含义如题目中描述。n=0表示输入数据的结束,不做处理。
输出
对于每个测试实例,输出在第n年的时候母牛的数量。每个输出占一行。
样例输入
2
4
5
0
样例输出
2
4
6

分析

先画图看一下牛的数量如何增长:
在这里插入图片描述
:题目的意思是母牛从第二年开始繁殖

把图中的1加起来来归纳前8年的个数:

第n年12345678
牛的总个数1234691319

现在的问题:怎么递归?
当然是用根据表格中的有限数据猜出通项公式再来进行递归:
F(1)=1
F(2)=2
F(3)=3
F(4)=4
F(5)=F(2)+F(4)

F(n)=F(n-3)+F(n-1)

  • 反过来理解通项公式:第n年的牛的数量=三年前牛的数量(每一只都生一只)+去年的牛的数量

参考代码

留给我自己看的(C语言版的代码):

#include<stdio.h>
int cow(int n)
{
    if(n ==1 ) return 1;
    else if(n == 2) return 2;
    else if(n == 3) return 3;
    else if(n == 4) return 4;
    else return cow(n-1)+cow(n-3);
}
int main()
{
    int n;
    while(~scanf("%d", &n))
    {
        if(n!=0) printf("%d\n",cow(n));
        else return 0;
    }
    return 0;
}

:题目的0~55范围在这里没有体现出来
反正测试数据也不会生成这个范围以外的数

运行结果

在这里插入图片描述
:这俩耗时貌似差不多…看不懂这些数据

  • 看看愚蠢的我最先开始的思路(给我自己看的,可能我以后就看不懂我最开始的思路了)
    除了第一只兔子,后面的所有的兔子的生长周期都一样,只是时间点不同而已(这里写成了兔子那是因为刚开始学的时候碰到了类似的复杂的问题,题目忘了找到再补充)。先放代码:
#include<stdio.h>
int cow(int n)
{
    if(n<=3&&n>0) return n;
    else
    {
        int num=n;
        for(int i=3;i<n;i++) num+=cow(n-i);
        return num;
    }
}
int main()
{
    int n;
    while(~scanf("%d", &n))
    {
        if(n!=0) printf("%d\n",cow(n-1)+1);
        else return 0;
    }
    return 0;
}
  • 哇…递归+循环,这不超时才怪
  • 解释一下输出cow(n-1)+1:去掉第一年特殊的情况,也就是从第2年开始算起
  • 解释一下cow这个函数:比如以第8年为例,返回7+cow(4)+cow(3)+cow(2)+cow(1),cow(4)=cow’(1)…不想码字直接上图在这里插入图片描述

我也被绕晕了,希望我再看到这个的时候看不懂
上面的代码的输出正确性已检验是正确的。

具体的递归在数据结构中再作具体补充
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值