有一对兔子,从出生后的第3个月起每个月都生一对兔子。小兔子长到第3个月后每个月又生一对兔子,假设所有的兔子都不死,问30个月内每个月的兔子总数为多少?
兔子数的规律,如下表所示:
月数 | 小兔子对数 | 中兔子对数 | 老兔子对数 | 兔子总数 |
---|---|---|---|---|
1 | 1 | 0 | 0 | 1 |
2 | 0 | 1 | 0 | 1 |
3 | 1 | 0 | 1 | 2 |
4 | 1 | 1 | 1 | 3 |
5 | 2 | 1 | 2 | 5 |
6 | 3 | 2 | 3 | 8 |
7 | 5 | 3 | 5 | 13 |
提示:不满1个月的兔子为小兔子,满1个月不满2个月的为中兔子,满3个月以上的为老兔子。
可以看出,每个月的兔子总数依次为1, 1, 2, 3, 5, 8, 13…这就是Fibonacci数列。总结数列规律即从前两个月的兔子数可以推出第3个月的兔子数。
该题是典型的迭代循环,即是一个不断用新值取代变量的旧值,然后由变量旧值递推出变量新值的过程。这种迭代与如下因素有关:初值、迭代公式、迭代次数。经过问题分析,算法可以描述为:
用C语言来描述迭代公式即为:
其中 fib 为当前新求出的兔子数,fib1为前一个月的兔子数,fib2 中存放的是前两个月的兔子数,然后为下一次迭代做准备,进行如下的赋值 fib2=fib1,fibl=fib,要注意赋值的次序,迭代次数由循环变量控制,表示所求的月数。
下面是完整的代码:
#include <stdio.h>
int main()
{
long fib1=1, fib2=1, fib;
int i;
printf("%12ld%12ld", fib1, fib2); /*输出第一个月和第二个月的兔子数*/
for(i=3; i<=30; i++)
{
fib = fib1 + fib2; /*迭代求出当前月份的兔子数*/
printf("%12ld", fib); /*输出当前月份兔子数*/
if(i % 4 == 0)
printf("\n"); /*每行输出4个*/
fib2 = fib1; /*为下一次迭代作准备,求出新的fib2*/
fib1 = fib; /*求出新的fib1*/
}
printf("\n");
return 0;
}
运行结果: