古典问题: 兔子总数
题目:
有一对兔子,从出生第3个月起每个月都生一对兔子,小兔子长到第3月后每个月又生一对兔子。假设所有兔子都不死,编程求第20个月总数为多少? 难点:从第3月起,能生小兔子的大兔子每个月都要生一对兔子。
分析:
月 份
小兔子
中兔子
大兔子
兔子总数
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
8
8
5
8
21
9
13
8
13
34
10
21
2
21
55
11
34
2
34
89
此时可找出规律:每个月总数是前两个月总数之和
方法一
从第三个月开始计算。前面两个月兔子数量确定(n1;n2),后面每个月的兔子数量等于前两个月兔子数量之和。前一个月的兔子数n2;前两个月的兔子数n1;所以从第三个月开始(n),兔子数量为n=n1+n2。此后前两个月的数目进行更新向后移动一月,方便下一个循环。
void main ()
{
int i,n,n1=1,n2=1;
for(i=3;i<=20;i++)
{
n=n1+n2;//本月兔子的数目(第三月开始)
n1=n2;//n1指向后移一位
n2=n;//n2指向后移一位
printf("第%2d个月兔子总数为%4d个\n",i,n);
}
printf("第20个月兔子总数为%d个",n);
}
方法二
从第一个月开始循环,将第一个月的数量先存储起来k=f1,在将后面两个月的兔子数量更新。后面第一个月的兔子数改变为后面第二个月f1=f2,后面第二个月的兔子数为前两个月之和f2=f2+k(f1未改变时的值)。
#include int main()
{
long f1=1,f2=1,k;
int i;
for(i=1;i<=20;i++ )
{
k=f1;//第i个月的兔子个数
f1=f2;//后面一个月的兔子个数
f2=k+f2;//后面二个月的兔子个数
printf("第%2d月有%4ld只兔子;\n", i,k);
}
}
方法三
每个循环处理两个月。每次更新,第一个月是前两个月之和f1+f2,第二个月也是前两个月之和f2=f2+f1(此时f1已经改变)
int main( )
{
long f1=1,f2=1;
int i;
//每次循环确定2个月的兔子个数
for(i=1;i<=10;i++)
{
printf("第%2d月有%4ld只兔子;\n第%2d月有%4ld只兔子;\n",2*i-1,f1,2*i,f2);
f1=f1+f2;//第2n-1个月兔子数
f2=f2+f1;//第2n个月兔子数
}
}
规律:每个月总数是前两个月总数之和