The rabbits have powerful reproduction ability. One pair of adult rabbits can give birth to one pair of kid rabbits every month. And after m months, the kid rabbits can become adult rabbits.
As we all know, when m=2, the sequence of the number of pairs of rabbits in each month is called Fibonacci sequence. But when m is not equal to 2, the problem seems not so simple. You job is to calculate after d months, how many pairs of the rabbits are there if there is exactly one pair of adult rabbits initially. You may assume that none of the rabbits dies in this period.
The input may have multiple test cases. In each test case, there is one line having two integers m(1<=m<=10), d(1<=d<=50), m is the number of months after which kid rabbits can become adult rabbits, and d is the number of months after which you should calculate the number of pairs of rabbits. The input will be terminated by m=d=0.
You must print the number of pairs of rabbits after d months, one integer per line.
实验课上写出来一次AC了,但是在TA修改过测试用例后WA。
这是实验课写的版本,思路是先计算成年兔子的数量:
不超过生长期的时候,成年兔子数量不变;如果超过了,就不断累加m月前的成年兔子数量(即m月前生下的兔子,现在已经成年)
然后计算未成年兔子的数量:
也就是加上m-1个月内每个月的成年兔子数量,因为这些成年兔子当时生的兔子现在都还没成年。
最后得到的就是兔子总数。
#include<stdio.h> long long rabbit(int m, int d); int main() { int m, d; while ( scanf("%d %d", &m, &d) && m != 0 ) { printf("%lld\n", rabbit(m, d)); } return 0; } long long rabbit( int m, int d ) { int i; long long rabbit[d]; rabbit[0] = 1; if ( m > d ) return d; else { for ( i = 1; i <= d; i++ ) { if ( i < m ) rabbit[i]= rabbit[ i - 1 ]; else rabbit[i] = rabbit[i - 1] + rabbit[i - m]; } /* 计算成年兔子的数量 */ for ( i = 1; i <= m - 1; i++ ) { rabbit[d] = rabbit[d] + rabbit[d - i]; } /* 加上未成年兔子的数量 */ return rabbit[d]; } }
现在倒回头看貌似思路很奇怪。
修改用例WA之后,换了一个思路重写,AC了。
这个思路没有将成年兔子和未成年兔子分开计算,而是直接用数组来进行递推(其实可以用递归,但是因为自己生理上对递归略反感,遇到这种题第一反应都是用数组和循环代替)。
在没有完成第一个生长期的时候,每个月都会多一对祖宗兔子生出来的小兔子。
在完成第一个生长期后,每个月生出来的小兔子的数量就是m个月前的兔子数量(m个月前的兔子,无论当时是大是小,现在一定全都成年了,所以能生小兔子)
这个思路其实就是不断地加入上个月生出来的兔子数。
1 long long rabbit( int m, int d ) 2 { 3 int i; 4 long long rabbit[d]; 5 6 rabbit[0] = 1; 7 8 for ( i = 1; i <= d; i++ ) 9 { 10 if ( i < m ) 11 { 12 rabbit[i]= rabbit[i - 1] + 1; 13 } 14 else 15 { 16 rabbit[i] = rabbit[i - 1] + rabbit[i - m]; 17 } 18 } 19 20 return rabbit[d]; 21 }
AC后开始将两种思路的结果进行对比,随便设置了一些测试用例,问题关键出现了
左边是WA的运行结果,右边是AC的那个。可以看到每当m>d时,兔子总是少一对
而WA的代码里设置了这样一个特例
if ( m > d ) return d;
很明显这是不对的。m > d时不应该return d,d只是祖宗兔子在这d个月里生的兔子,没有算进这对祖宗兔子本身。
if ( m > d ) { return 1 + d; }
修改后就AC了。说实话我也不知道自己当时怎么想的,为什么不加上祖宗兔子呢……
#include<stdio.h> long long rabbit(int m, int d); int main() { int m, d; while ( scanf("%d %d", &m, &d) && m != 0 ) { printf("%lld\n", rabbit(m, d)); } return 0; } long long rabbit( int m, int d ) { int i; if ( d == 0 ) { return 1; } else if ( m > d ) { return rabbit(m, d - 1) + 1; } else { return rabbit(m, d - 1) + rabbit(m, d - m); } }
输入前两个样例,得到的是正确的答案。不过一输入1 50,果然卡住。丢进sicily,果然超时了。