问题内容
Description
二哥培养出了一种繁殖能力很强的兔子。
这种兔子在出生后的第一个月,能够生出a对兔子;第二个月,能够生出b对兔子;第三个月以及以后的每个月,都可以生出c对兔子。
二哥对此很感兴趣,若他有一对刚出生的兔子,按照最理想的模式繁殖,并假设兔子不死,二哥想知道最少需要几个月这些兔子可以遍布地球的每个角落。
为了回答这个问题,二哥想要知道这种兔子在第N个月时的对数。
Input Format
输入只有一行,四个数,分别为a,b,c,N ( 0≤a≤b≤c≤100,N≤10000≤a≤b≤c≤100,N≤1000 ),其含义为题目所述。
Output Format
输出只有一个数,为第N个月兔子的对数。
Sample Input
0 1 1 11
Sample Output
144
代码实现
#include <stdio.h>
#include <memory.h>
#define LEN 400
#define MOD 1000000
unsigned int calc[4][LEN];
int len[4] = {1,1,1,1};
int a, b, c;
int s0 = 1, s1 = 1, s2 = 2, s3 = 3;
int main(){
int N, i, j, temp, up, length;
scanf("%d %d %d %d", &a, &b, &c, &N);
calc[1][0] = 1;
for(i = 0,s0 = 0,s1 = 1,s2 = 2,s3 = 3; i < N; i++)
{
memset(calc[s0], 0, LEN * sizeof(int));
for (j = 0; j < len[s1];j ++){
temp = calc[s3][j] * c + calc[s2][j] * b + calc[s1][j] * a;
up = temp / MOD;
if(up){
calc[s0][j + 1] += temp / MOD;
if(j + 1 + 1 > len[s0]){
len[s0] = j + 1 + 1;
}
}
calc[s0][j] += temp % MOD;
}
for (j = 0; j < len[s1];j ++){
temp = calc[s3][j] + calc[s2][j];
up = temp / MOD;
if(up){
calc[s2][j + 1] += temp / MOD;
if(j + 1 + 1 > len[s2]){
len[s2] = j + 1 + 1;
}
}
calc[s2][j] = temp % MOD;
}
temp = s3;
s3 = s2;
s2 = s1;
s1 = s0;
s0 = temp;
}
memset(calc[s0], 0, LEN * sizeof(int));
for (i = 2,length = len[1]; i <= 3; i++){
if(len[i] > length){
length = len[i];
}
}
for (j = 0; j < length; j++)
{
temp = (calc[s1][j] + calc[s2][j] + calc[s3][j]);
up = temp / MOD;
if (up)
{
calc[s0][j + 1] += temp / MOD;
if (j + 1 + 1 > length)
{
length = j + 1 + 1;
}
}
calc[s0][j] += temp % MOD;
}
for (i = length - 1; i >= 0; i--){
if(i != length - 1){
printf("%06u", calc[s0][i]);
}
else
{
printf("%u", calc[s0][i]);
}
}
printf("\n");
return 0;
}
时间:12ms 空间:9132kb
斐波那契数列朴素实现,搜了一下开销竟然最小,一下子方了。