兔子繁殖问题
问题描述
兔子繁殖问题:假定一对大兔子每月能生一对小兔子,且每对新生的小兔子经过一个月可以长成一对大兔子,具备繁殖能力,如果不发生死亡,且每次均生下一雌一雄,问一年后共有多少对兔子?
这个问题是今天群里的打卡问题,把我自己的思路摆上来,然后用递归和循环的方式分别实现。
思路和代码
这里如果往深里想,很容易犯晕,我们做这样的规定:每对兔子都是月初出生,月底长成,本月新生的兔子不会繁殖。依据这个规定,按照月份、小兔子的对数、成熟兔子的对数列个表格(前6个月的,月初统计)。
统计 | 1月 | 2月 | 3月 | 4月 | 5月 | 6月 |
---|---|---|---|---|---|---|
小兔子对数 | 0 | 1 | 1 | 2 | 3 | 5 |
成熟兔子对数 | 1 | 1 | 2 | 3 | 5 | 8 |
合计 | 1 | 2 | 3 | 5 | 8 | 13 |
观察一下,小兔子、成熟兔子、合计均是一个斐波那契数列。区别就是初始值不一样。列表到这里其实就可以写代码了。参考今天的递归,可以很方便的写出递归形式的代码:
int young_rabbit_rec(int n) //recursion way
{
if (1 == n)
return 0;
else if (2 == n)
return 1;
else
return young_rabbit_rec(n - 1) + young_rabbit_rec(n - 2);
}
int mature_rabbit_rec(int n) //recursion way
{
if (n >= 3)
return mature_rabbit_rec(n - 1) + mature_rabbit_rec(n - 2);
else
return 1;
}
关于初值,使用分支语句处理即可。有了递归方法,循环方法也很容易就可以写出来:
int young_rabbit(int n)//loop way
{
if (1 == n)
{
return 0;
}
if (2 == n)
{
return 1;
}
int a = 0;
int b = 1;
int c = 1;
while (n >= 3)
{
c = a + b;
a = b;
b = c;
n--;
}
return c;
}
int mature_rabbit(int n)//loop way
{
int a = 1;
int b = 1;
int c = 1;
while (n >= 3)
{
c = a + b;
a = b;
b = c;
n--;
}
return c;
}
为了验证是否和预期一致:
int main()
{
int month = 0;
while (scanf("%d", &month) != EOF)
{
int i = 0;
printf("=============循环实现==============\n");
printf("\n");
for (i = 1; i <= 12; i++)
{
printf("第%d月共有%d对小兔子,%d对大兔子。\n", i, young_rabbit(i),mature_rabbit(i));
printf("第%d月共有%d对兔子。\n",i, young_rabbit(i) + mature_rabbit(i));
printf("\n");
}
printf("=============递归实现==============\n");
printf("\n");
for (i = 1; i <= 12; i++)
{
printf("第%d月共有%d对小兔子,%d对大兔子。\n", i, young_rabbit_rec(i), mature_rabbit_rec(i));
printf("第%d月共有%d对兔子。\n", i, young_rabbit_rec(i) + mature_rabbit_rec(i));
printf("\n");
}
}
return 0;
}