【蓝蓝计算机考研算法】-day07-统计每个月兔子总数

180 阅读2分钟

10、统计每个月兔子的总数

有一种兔子,从出生后第3个月起每个月都生一只兔子,小兔子长到第三个月后每个月又生一只兔子。

例子:假设一只兔子第3个月出生,那么它第5个月开始会每个月生一只兔子。

一月的时候有一只兔子,假如兔子都不死,问第n个月的兔子总数为多少?

数据范围:输入满足 1≤n≤31

输入描述:

输入一个int型整数表示第n个月

输出描述:

输出对应的兔子总数

思路一

1.根据表可发现,当前月数=前一个月+前前一个月 如:3月只数=2月只数+1月只数
2.利用if和for循环累计复制。计算出第X月兔子数
难点: 对于如何将上个月和上上个月值进行累加到当月。
解决:用交换赋值法 如:

count = m1 + m2;//3月份时候3月=1+2
m1 = m2;//将2月份赋值给一月份
m2 = count;//将3月份复制给2月份 若是4月=3+2

月数只数
11
21
32
43
55

具体实现

#include<stdio.h>

int main()
{
    int n = 31, m1 = 1,m2=1, count = 0;//n代表月数 count 代表兔子总数,m1和m2分别代表第一个月和第二个月
    printf("输入月份数:");
    scanf_s("%d", &n);
   if (n == 1 || n == 2) {
       printf("第%d个月共有%d 只兔子。\n",n, m1); 
   }
   else  if (n <=31) {
       for (int i = 3; i <= n; i++) {
           count = m1 + m2;//3月份时候3月=1+2
           m1 = m2;//2月份赋值给一月份
           m2 = count;//3月份复制给2月份 若是4月=3+2          
      }
       printf("第 %d个月共有%d 只兔子。\n", n, count);
   }
   else {
       printf("输入超出月数\n");
       return 0;
   }
    return 0;
}

运行结果

输入月份数:66个月共有8 只兔子。

复杂度

时间:O(n)————n为输入的月数,代码中运行次数最多的就是if(n<=30)下的循环语句.    

空间:O(1)——没有用到存储,所以空间复杂度为常数  

思路二

思路参考大神的,详情:蓝蓝计算机考研算法-day07统计每个月兔子总数 - 掘金 (juejin.cn)  

递归公式** f(n)=f(n−1)+f(n−2)f(n)=f(n−1)+f(n−2)**,其实就是斐波那契数列,然后利用此公式逐层递归即可。  

image.png  

具体实现

#include <stdio.h>

int f(int n) {//递归方法
    if (n <= 2) {//n为月数
        return 1;
    }
    else {
        return f(n - 1) + f(n - 2);//本月数=前两个月数目相加
    }
}

int main() {
    int n;

    printf("请输入月份:");
    scanf_s("%d", &n);

    printf("第%d个月的兔子总数为:%d\n", n, f(n));

    return 0;
}

运行结果

image.png

  • 时间复杂度 O(2^n) --- 遍历整个二叉树(节点数)可理解为二叉树的层数
  • 空间复杂度 O(n) --- 递归栈的深度为 n

小结

找到思路,无法用代码将其表示出来,很基本的逻辑还没有熟练掌握。需要多加练习。  

今天犯错误将 printf()的输出里面的变量加上了&取地址,导致查找了很久,用最简单的尝试方法最终还是发现了这个错误。