题目
一对兔子,从出生后第3个月起每个月都生一对兔子。小兔子长到第3个月后每个月又生一对兔子。假如兔子都不死,请问第1个月出生的一对兔子,至少需要繁衍到第几个月时兔子总数才可以达到N对?
输入格式:
输入在一行中给出一个不超过10000的正整数N。
输出格式:
在一行中输出兔子总数达到N最少需要的月数。
输入样例:
30
输出样例:
9
分析
兔子繁衍问题本质上是斐波那契数列问题。
所以有递归和迭代两种解决思路。
- 递归
递归思想在于大事化小,递归存在限制条件,每次递归调用接近该条件。 - 迭代
由于递归会有大量的重复计算。
题解
- 递归
//斐波那契数列
// 1 1 2 3 5 8 13 21 .....
//描述第n个斐波那契数列
//n <= 2 1
//n > 2 f(n-1)+f(n-2)
#include <stdio.h>
int Fib(int n)
{
if (n <= 2)
return 1;
else
return Fib(n - 1) + Fib(n - 2);
}
int main()
{
int n;
scanf("%d", &n);
int month = 0;
while (++month)
{
if (n == Fib(month))
{
printf("%d", month);
break;
}
}
return 0;
}
然后就出现了运行超时的问题。
- 迭代
#include <stdio.h>
int Fib(int n)
{
int a = 1;
int b = 1;
int c = 1;
while (n > 2)
{
c = a + b;
a = b;
b = c;
n--;
}
return c;
}
int main()
{
int n;
scanf("%d", &n);
int month = 0;
while (++month)
{
if (n == Fib(month))
{
printf("%d", month);
break;
}
}
return 0;
}
运行还是超时,,,,emmm事情不对。
夯吃夯吃又改了,超时,那我不调用函数不就好了。
#include <stdio.h>
int main()
{
int n;
int month = 1;
scanf("%d", &n);
if (n == 1)
month = 1;
else
{
int a = 1;
int b = 1;
int c = 1;
month = 2;
while (c < n)
{
c = a + b;
a = b;
b = c;
month++;
}
}
printf("%d", month);
return 0;
}
总算过了。
我们回过头来分析一下这段代码和之前两次有什么区别。
- 请问第1个月出生的一对兔子,至少需要繁衍到第几个月时兔子总数才可以达到N对?
可以知道,最后结果c是可以大于等于n对的。 - 函数每次调用需要耗时间,不太划算。
- 第1个月和第2个月兔子对数都是1,所以在之前就需要先分类讨论。