兔子繁殖问题

时间:2020-11-29 11:23:11

 

/*兔子繁殖问题。
 设有一对新生的兔子,从第三个月开始他们每个月都生一对兔子,新生的兔子从第三个月开始又每个月生一对兔子。
 按此规律,并假定兔子没有死亡,20个月后共有多少个兔子?要求编写为控制台程序。*/

/*解题思路
 斐波那契数列问题
 f(1) = 1(第1个月有一对兔子)
 f(2) = 1(第2个月还是一对兔子)
 f(3) = 2(原来有一对兔子,第3个开始,每个月生一对兔子)
 f(4) = 3(原来有两对兔子,有一对可以生育)
 f(5) = 5(原来有3对兔子,第3个月出生的那对兔子也可以生育了,那么现在有两对兔子可以生育)
 f(6) = 8(原来有5对兔子,第4个月出生的那对兔子也可以生育了,那么现在有3对兔子可以生育)
 ..............
 由以上可以看出,第n个月兔子的对数为
 f(n) = f(n - 1) + f(n - 2);
 f(n-1)是上个月的兔子数量,是原来有的。
 f(n-2)是可以生育的兔子数,即多出来的数量。第n-2个月开始后的第3个月是第n个月,此时第n-2个月时的兔子都可以生育了。

 程序如下:*/
import java.util.*;

public class 兔子繁殖问题 {

	// 方法一:采用斐波那契数递归思想
	public static int f(int n) {
		if (n == 1 || n == 2)
			return 1;
		else
			return f(n - 1) + f(n - 2);
	}

	// 方法二:为了再提高执行效率,可以采用打表思想
	public static int f[]=new int[1000];
	public static int f2(int n) {
		
		for (int i = 1; i < n; i++)
			f[i] = i > 2 ? f[i - 2] + f[i - 1] : 1;
		return f[n] = n > 2 ? f[n - 2] + f[n - 1] : 1;
	}


	// 方法三:为了节省空内存间,可采用迭代思想

	static int f3(int n) {
		int a, b, sum;
		a = b = sum = 1;
		if (n == 1 || n == 2)
			return 1;
		else {
			for (int i = 3; i <= n; i++) {
				sum = a + b;
				a = b;
				b = sum;
			}
			return sum;
		}
	}

	// 方法四:这是蓝桥杯一填空题,模拟母牛生产过程,效率低的可怕,想吐槽一下

	private int age;

	public 兔子繁殖问题 afterYear() {
		age++;
		return age > 2 ? new 兔子繁殖问题() : null;
	}

	public static void f4(int n) {
		List<兔子繁殖问题> list = new ArrayList<兔子繁殖问题>();
		list.add(new 兔子繁殖问题());

		for (int i = 0; i < n; i++) {
			int cowCount = list.size();
			for (int j = 0; j < cowCount; j++) {
				兔子繁殖问题 rabbit = list.get(j).afterYear();
				if (rabbit != null) {

					list.get(j).afterYear();
					list.add(rabbit);
				}
			}

		}
		System.out.println("第" + n + "个月有兔子" + list.size() + "只");
	}

	public static void main(String[] args) {
		long start = System.currentTimeMillis();
		for (int i = 1; i < 30; i++) {
			// System.out.println("第" + i + "个月有兔子" + f(i) + "只");
			System.out.println("第" + i + "个月有兔子" + f2(i) + "只");
			// System.out.println("第" + i + "个月有兔子" + f3(i) + "只");
			// f4(i);
		}
		double end = System.currentTimeMillis();
		double sumTime = (end - start) / 1000.0;
		System.out.println("执行时间为:" + sumTime + "秒");
	}

}

 

 

 

运行结果
方法一:
第1个月有兔子1只
第2个月有兔子1只
第3个月有兔子2只
第4个月有兔子3只
第5个月有兔子5只
第6个月有兔子8只
第7个月有兔子13只
第8个月有兔子21只
第9个月有兔子34只
第10个月有兔子55只
第11个月有兔子89只
第12个月有兔子144只
第13个月有兔子233只
第14个月有兔子377只
第15个月有兔子610只
第16个月有兔子987只
第17个月有兔子1597只
第18个月有兔子2584只
第19个月有兔子4181只
第20个月有兔子6765只
第21个月有兔子10946只
第22个月有兔子17711只
第23个月有兔子28657只
第24个月有兔子46368只
第25个月有兔子75025只
第26个月有兔子121393只
第27个月有兔子196418只
第28个月有兔子317811只
第29个月有兔子514229只
执行时间为:0.009秒

 

 

方法二
第1个月有兔子1只
第2个月有兔子1只
第3个月有兔子2只
第4个月有兔子3只
第5个月有兔子5只
第6个月有兔子8只
第7个月有兔子13只
第8个月有兔子21只
第9个月有兔子34只
第10个月有兔子55只
第11个月有兔子89只
第12个月有兔子144只
第13个月有兔子233只
第14个月有兔子377只
第15个月有兔子610只
第16个月有兔子987只
第17个月有兔子1597只
第18个月有兔子2584只
第19个月有兔子4181只
第20个月有兔子6765只
第21个月有兔子10946只
第22个月有兔子17711只
第23个月有兔子28657只
第24个月有兔子46368只
第25个月有兔子75025只
第26个月有兔子121393只
第27个月有兔子196418只
第28个月有兔子317811只
第29个月有兔子514229只
执行时间为:0.002秒
 
方法三:

第1个月有兔子1只
第2个月有兔子1只
第3个月有兔子2只
第4个月有兔子3只
第5个月有兔子5只
第6个月有兔子8只
第7个月有兔子13只
第8个月有兔子21只
第9个月有兔子34只
第10个月有兔子55只
第11个月有兔子89只
第12个月有兔子144只
第13个月有兔子233只
第14个月有兔子377只
第15个月有兔子610只
第16个月有兔子987只
第17个月有兔子1597只
第18个月有兔子2584只
第19个月有兔子4181只
第20个月有兔子6765只
第21个月有兔子10946只
第22个月有兔子17711只
第23个月有兔子28657只
第24个月有兔子46368只
第25个月有兔子75025只
第26个月有兔子121393只
第27个月有兔子196418只
第28个月有兔子317811只
第29个月有兔子514229只
执行时间为:0.002秒
 
方法四:

第1个月有兔子1只
第2个月有兔子1只
第3个月有兔子2只
第4个月有兔子3只
第5个月有兔子5只
第6个月有兔子8只
第7个月有兔子13只
第8个月有兔子21只
第9个月有兔子34只
第10个月有兔子55只
第11个月有兔子89只
第12个月有兔子144只
第13个月有兔子233只
第14个月有兔子377只
第15个月有兔子610只
第16个月有兔子987只
第17个月有兔子1597只
第18个月有兔子2584只
第19个月有兔子4181只
第20个月有兔子6765只
第21个月有兔子10946只
第22个月有兔子17711只
第23个月有兔子28657只
第24个月有兔子46368只
第25个月有兔子75025只
第26个月有兔子121393只
第27个月有兔子196418只
第28个月有兔子317811只
第29个月有兔子514229只
执行时间为:0.157秒