老鼠繁殖问题(老鼠有死亡)
同学的同学问了这样一个问题:
有一对小老鼠,出生一周后长成一对大老鼠,两周后这对老鼠生出第一对小老鼠,三周后上周出生的小老鼠变成大老鼠,而原来的大老鼠又生出了一对小老鼠之后便死了,四周后,第一对出生的小老鼠(此时已经是大老鼠)又生出了一对小老鼠,此时共有三对老鼠。编程,计算N周后有多少对老鼠?
首先,这个问题如果小鼠没有死亡,就是一个典型的斐波那契数列(事实上斐波那契数列最早就是描述兔子繁殖的)
加上死亡,就需要重新考虑一下了~
方法一:
自然是超级水的同时很管用的----找规律法。
周数 0-----1-----2-----3-----4-----5-----6-----7.............
鼠数 1-----1-----2-----2-----3-----4-----5-----7.............
很容易就发现,相邻两个的和是隔一周的数,比如:2周和3周的和是5周,4周和5周的和是7周。
所以递归之:
1 #include <iostream> 2 3 using namespace std; 4 5 int mouse(int n) 6 { 7 if (0 == n) 8 { 9 return 1; 10 } 11 else if (1 == n) 12 { 13 return 1; 14 } 15 else if (2 == n) 16 { 17 return 2; 18 } 19 else 20 { 21 return mouse(n-2)+mouse(n-3); 22 } 23 } 24 25 int main() 26 { 27 int n; 28 29 while (cin >> n) 30 { 31 cout << mouse(n) << endl; 32 } 33 34 return 0; 35 }
方法二:
递归太慢了,而且对于这个问题,显然没复杂到只能用递归。
第二个方法就是手动模拟整个繁殖过程,开个数组存不同年龄段的老鼠。也就是改成用递推做~
1 #include <iostream> 2 3 using namespace std; 4 5 int num(int); 6 7 int main() 8 { 9 int n; 10 while (cin >> n) 11 { 12 cout << "The answer is " << num(n) << endl; 13 } 14 15 16 return 0; 17 } 18 19 int num(int n) 20 { 21 int a[3] = {1, 0, 0}; 22 int t1, t2; 23 24 for (int i=0; i<n; ++i) 25 { 26 t1 = a[1]; 27 t2 = a[2]; 28 a[1] = a[0]; 29 a[2] = t1; 30 a[0] = t1 + t2; 31 32 cout << i+1 << " has " << (a[0]+a[1]+a[2]) << " mice" << endl; 33 } 34 return (a[0]+a[1]+a[2]); 35 }
================================================================
又有下文了,同学的同学的老师说要大数也能处理的。
补充一个:
1 #include <iostream> 2 #include <cstring> 3 4 const int MAX = 100000; 5 6 using namespace std; 7 8 void add(char *str1, char *str2, char *str3); 9 void num(int, char *); 10 11 int main() 12 { 13 int n; 14 char s[MAX]; 15 16 while (cin >> n) 17 { 18 num(n, s); 19 cout << "The answer is " << s << endl; 20 } 21 22 23 return 0; 24 } 25 26 void num(int n, char *s) 27 { 28 //Big Int 29 char a0[MAX]; 30 char a1[MAX]; 31 char a2[MAX]; 32 char t1[MAX]; 33 char t2[MAX]; 34 35 strcpy(a0, "1"); 36 strcpy(a1, "0"); 37 strcpy(a2, "0"); 38 39 for (int i=0; i<n; ++i) 40 { 41 strcpy(t1, a1); 42 strcpy(t2, a2); 43 strcpy(a1, a0); 44 strcpy(a2, t1); 45 add(t1, t2, a0); 46 } 47 char temp1[MAX]; 48 char temp2[MAX]; 49 char temp3[MAX]; 50 strcpy(temp1, a0); 51 add(temp1, a1, temp2); 52 add(temp2, a2, temp3); 53 strcpy(s, temp3); 54 } 55 56 void add(char *str1, char *str2, char *str3) 57 { 58 int i, j, i1, i2, tmp, carry; 59 int len1 = strlen(str1); 60 int len2 = strlen(str2); 61 char ch; 62 63 i1 = len1 - 1; 64 i2 = len2 - 1; 65 j = carry = 0; 66 67 for ( ; i1>=0 && i2>=0; ++j, --i1, --i2) 68 { 69 tmp = str1[i1] - '0' + str2[i2] - '0' + carry; 70 carry = tmp / 10; 71 str3[j] = tmp % 10 + '0'; 72 } 73 while (i1 >= 0) 74 { 75 tmp = str1[i1--] - '0' + carry; 76 carry = tmp/10; 77 str3[j++] = tmp%10 + '0'; 78 } 79 while (i2 >= 0) 80 { 81 tmp = str2[i2--] -'0' + carry; 82 carry = tmp/10; 83 str3[j++] = tmp%10 + '0'; 84 } 85 86 if (carry) 87 { 88 str3[j++] = carry + '0'; 89 } 90 str3[j] = '\0'; 91 92 for (i=0, --j; i<j; ++i, --j) 93 { 94 ch = str3[i]; 95 str3[i] = str3[j]; 96 str3[j] = ch; 97 } 98 }