• 关于“古典问题:有一对兔子,从出生后第3个月起每个月都生一对兔子……” 理清问题,无往而不胜


    被一窝兔子绊倒!

    古典问题:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少?

    本人是在搜问题时,发现有伙伴在百度提问,并试着理解并寻找问题发生的根源 —— 误解了题目,还是解题困难。通过接受和理解问题提出者的困惑后,发现疑惑和误解是可以理解的,我试着为题目增加一些限制和说明,使得对题目的把握更加准确,或者说减少题目本身存在的歧义,使之更加明确。至于问题的解法,方法有多种,而且提供解法的文章数不胜数,不再赘述,如需了解,请再简单搜索一下。

    (百度问题:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子.如果您看到这两处的说法一样,不要奇怪,都出自于本人。其中内容包括问题的直接回答,及对其中一个回答者的内容进行评论,即回答了其中一个回答者的回复

    题干分析(减少歧义)不可将 “第3个月”看成了(理解成)“隔3个月”。准确的理解是“如 当下是1月初,2月初则是第二月,3月初就是第三个月”。这里如果说成两月即61天(2个月,忽略闰二月,假如闰二月时,按月算)后。这样会减少不是歧义。

    问题解析:这是一个典型的“波非那切数列”:前面相邻两项之和,构成了后一项(即:后一项,总等于前两项之和)。

    关于:“前面相邻两项之和,构成了后一项”的理解:(
    依据:“第3个月起每个月都生一对”(这里容易造成误解的是,第3个月起,这个起始时间点,是指月初还是月末的问题,从这个经典问题的初衷来说,是指的月初)。
    因此:“第3个月,即隔2个月(约61天,闰月则忽略并按月来算)就发生”。
    结论:
    (1) 上一个月的兔子(n),在下一个月,保持到下一月(n);即 老兔数 = 上月兔子总数。
    (2) 第3月出生的兔仔,由上上月(第 前3月)的兔子所生,且是1对 生 1对,1:1的比例。及 兔仔数 = 上上月的兔子总数。
    (3) 总数 = 上月兔子总数 + 上上月的兔子总数(也即 相邻两项之和)

    个人的一段小解法:

    (1)迭代算法方式

     1 package com.activitiserver;
     2 
     3 public class server {
     4 
     5     // 1   1    2   3   5
     6     public static void main(String[] args) {
     7         int month;
     8         for (int i = 1;i<10;i++){
     9             month = i;
    10             int count = printCountByMonth(month);
    11             System.out.println("第" + month + "月,小兔数为:" + count +"(对)");
    12             System.out.println();
    13         }
    14     }
    15 
    16     public static int printCountByMonth(int month){
    17         if (month < 1) throw new RuntimeException("月数不可小于1个月");
    18         int first = 1;
    19         int second = 1;
    20         int third = 0;
    21         if (month == 1 || month == 2) return 1;
    22         boolean flag = true;
    23         while (month > 0){
    24             first = second;
    25             second = third;
    26             third = first + second;
    27             month --;
    28             if (flag){
    29                 flag = false;
    30             }else{
    31                 System.out.print(",");
    32             }
    33             System.out.print(third);
    34         }
    35         System.out.println();
    36         return third;
    37     }
    38 }

    运行结果: 

    第1月,小兔数为:1(对)
    
    第2月,小兔数为:1(对)
    
    1,1,2
    第3月,小兔数为:2(对)
    
    1,1,2,3
    第4月,小兔数为:3(对)
    
    1,1,2,3,5
    第5月,小兔数为:5(对)
    
    1,1,2,3,5,8
    第6月,小兔数为:8(对)
    
    1,1,2,3,5,8,13
    第7月,小兔数为:13(对)
    
    1,1,2,3,5,8,13,21
    第8月,小兔数为:21(对)
    
    1,1,2,3,5,8,13,21,34
    第9月,小兔数为:34(对)
    
    
    Process finished with exit code 0

     (2)递归算法方式

     1 public class BFNQFun {
     2     public static void main(String[] args) {
     3         int in = 9;
     4         int count = getCount(in);
     5         System.out.println();
     6         System.out.println("in = " + in+ ",getCount = " + count);
     7     }
     8 
     9     public static int getCount(int in){
    10         System.out.print(in + ",");
    11         if (in <= 0) return 1;
    12         if (in == 1) return 1;
    13         return getCount(in - 1) + getCount(in - 2);
    14     }
    15 }

    运行结果:(为了便于阅读,对下面的换行是手动修改的,并非原样,但数据总数不变)  

    9,8,7,6,5,4,3,2,1,0,1,2,1,0,3,2,1,0,1,4,3,2,1,0,1,2,1,0,
    5,4,3,2,1,0,1,2,1,0,3,2,1,0,1,6,5,4,3,2,1,0,1,2,1,0,3,2,
    1,0,1,4,3,2,1,0,1,2,1,0,7,6,5,4,3,2,1,0,1,2,1,0,3,2,1,0,
    1,4,3,2,1,0,1,2,1,0,5,4,3,2,1,0,1,2,1,0,3,2,1,0,1,
    
    in = 9,getCount = 55

    小结:

    从打印的“,”符号统计:

    迭代算法:35个“,”  .

    递归算法:108个“,” .

    即可得出:效率 递归算法 弱与 迭代算法,也就是说,本次运算中 递归算法 优于 迭代算法。

  • 相关阅读:
    C#与面向对象编程语言
    Windows Communication Fundation(WCF)的安装和一些疑惑
    Windows Communication Foundation入门(Part Two)
    Design & Pattern团队公告
    解决方案、项目、程序集、命名空间
    你注意到了吗?
    我的个人主页
    PetShop与设计
    CKEditor/CKFinder升级心得
    [转贴]基于UDP、TCP协议的C#网络编程之一
  • 原文地址:https://www.cnblogs.com/bridgestone29-08/p/13228994.html
Copyright © 2020-2023  润新知