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

本文探讨了古典兔子繁殖问题的两种解决策略:一是通过迭代实现的逐月相加法,二是递归法计算兔子总数。两种方法分别展示了如何保证a始终小于b以及递归公式f(n)=f(n-1)+f(n-2)的应用,并提供了示例代码和常见问题解析。
摘要由CSDN通过智能技术生成

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

A.普通方法: 保证a一直小于b(当n>=3时)

1.核心代码

while(true){
     if(n==1||n==2){
        System.out.println("第"+n+"个月兔子总数为:"+sum+"对");
        flag=true;
     }else if(n>=3){
        //相加次数为n-2次
        for (int i =n-2; i>0; i--) {
       //保证每次a都会小于b
             sum=a+b;
             a=b;
             b=sum;
             //测试语句:System.out.println("a的值为:"+a+",b的值为:"+b);
         }
       System.out.println("第"+n+"个月兔子总数为:"+sum+"对");
       flag=true;  
       }else{
             flag=false;
             System.out.println("输入n的值有误,请检查后重新输入");
             System.out.println("请再次输入n的值");
             n=scanner.nextInt();
       }
       if(flag){
             break;
       }
}

2.常见问题点分析

2.1 如何保证每次a<b(当n>=3)???

解决方案: 建立一个sum变量用来接收每月的兔子总数,

​ 每次接收完后,b会把原来的b值传给a

​ 然后b就就接收sum的值

2.2 布尔类型变量flag的作用是什么???

解答:flag默认初始值为true

​ a.当输入的n不符合条件时,flag值变为false

​ 此时无法使用break关键字跳出循环

​ 随后界面提示重新输入n的值

​ b.当输入的n符合条件时,flag值不变

​ 得到兔子总数sum后

​ 可以使用break跳出循环

​ c.对于a情况,再次输入一个正确的n值

​ 会得到兔子总数且跳出循环

2.3 内层循环次数(相加次数)为多少???

​ 解答如下所示:
当n=3,1+1=2,需要相加1次

当n=4时 1+1=2,1+2=3;需要相加2次

当n=5时 1+1=2,1+2=3,2+3=5;需要相加3次
​因而需要相加次数=n-2

3.运行截图

3.1 首次输入有误且n=1

在这里插入图片描述

3.2 首次输入有误且n=2

在这里插入图片描述

3.3 首次输入有误且n=5

在这里插入图片描述

3.4 首次输入正确且n=8

在这里插入图片描述

4.源代码

import java.util.Scanner;
public class TestRabbit01 {
    public static void main(String[] args) {
        System.out.println("题目:古典问题:有一对兔子,从出生后第 3 个月起每个月都生一对兔子\n小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,问n个月的兔子总数为多少?");
        //前提条件: 第一个月时,兔子总数为1对,第二个月时,兔子总数为1对
        int a=1,b=1;
        System.out.println("请输入n的值:");
        Scanner scanner=new Scanner(System.in);
        int n=scanner.nextInt();
        boolean flag=true;
        //用来判断是否跳出循环,默认为true
        // 当n输入有误时,flag=false,此时不会跳出循环
        int sum=1;
        //保存每月兔子总数
        while(true){
            if(n==1||n==2){
                flag=true;
                System.out.println("第"+n+"个月兔子总数为:"+sum+"对");
            }else if(n>=3){
                //相加次数为n-2次
                for (int i =n-2; i>0; i--) {
                   //保证每次a都会小于b
                   sum=a+b;
                   a=b;
                   b=sum;
                   //System.out.println("a的值为:"+a+",b的值为:"+b);
                }
                flag=true;
                System.out.println("第"+n+"个月兔子总数为:"+sum+"对");
            }else{
                flag=false;
                System.out.println("输入n的值有误,请检查后重新输入");
                System.out.println("请再次输入n的值");
                n=scanner.nextInt();
            }
            if(flag){
                break;
            }
        }

    }
}

B.递归法: f(n)=f(n-1)+f(n-2)(n>3)

1.核心代码

public static int Sum(int N){
        //如果输入的月份为第一个月或第二个月
        //那兔子的总数就为1
        if(N==1||N==2){
            return 1;
        }
        //当N>=3时,就会执行递归方法,方法内进行方法的调用
        return Sum(N-1)+Sum(N-2);
}

2.常见问题点分析

2.1 如何保证第一个月和第二个月的兔子总数为1???

解决方案: 在函数Sum里面对接收过来的值N进行判断

​ 若N值为1或者N值为2时,函数的返回值为1

2.2 f(N)=f(N-1)+f(N-2)(n>=3)的由来???

解答如下所示:
当N=3时,f(3)=1+1=f(1)+f(2)=2

当N=4时f(4)=1+2=f(2)+f(3)=3

当N=5时f(5)=2+3=f(3)+f(4)=5

因而f(N)=f(N-2)+f(N-1)=f(N-1)+f(N-2)

2.3 布尔类型变量flag的作用是什么???

​ 解答如下所示:
1.当n不符合条件时,flag=false,需要重新输入n的值

​ 然后进行下一轮的n值判断,

​ 若结果还是不符合,就重新执行上述操作

​ (重新输入n且进行判断)

​ 2.当n符合条件时,flag=true,

​ 得到兔子总数后会跳出循环

3.运行截图

3.1 首次输入有误且n=1

在这里插入图片描述

3.2 首次输入有误且n=2

在这里插入图片描述

3.3 首次输入有误且n=4

在这里插入图片描述

3.4 首次输入正确且n=6

在这里插入图片描述

4.源代码

import java.util.Scanner;
public class TestRabbit02 {
    public static void main(String[] args) {
        System.out.println("题目:古典问题:有一对兔子,从出生后第 3 个月起每个月都生一对兔子\n小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,问n个月的兔子总数为多少?");
        //前提条件: 第一个月时,兔子总数为1对,第二个月时,兔子总数为1对
        System.out.println("请输入n的值:");
        Scanner scanner=new Scanner(System.in);
        int n=scanner.nextInt();
        boolean flag=true;
        int sum=0;
        //定义sum变量用来存放兔子的总数
        while(true){
            if(n<1){
                //此时不满足跳出循环条件,flag值应为false
                flag=false;
                System.out.println("输入的n值(第几个月)有误,请检查后重新输入");
                System.out.println("请再次输入n的值");
                n=scanner.nextInt();
            }else{
                sum=Sum(n);
                //保证非首次输入正确的n值时,程序也能正确执行
                flag=true;
                //符合条件,跳出循环
                if (flag) {
                    break;
                }
            }
        }
        System.out.println("第"+n+"个月兔子总数为:"+sum+"对");
    }
    public static int Sum(int N){
        //如果输入的月份为第一个月或第二个月
        //那兔子的总数就为1
        if(N==1||N==2){
            return 1;
        }
        return Sum(N-1)+Sum(N-2);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

SSS4362

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值