Project_Euler-25 题解
题目
思路
大体思路是这样的:从小到大枚举斐波那契数,判断每个斐波那契数的位数。如果大于1000位,就输出并退出。
其中有一下几个问题需要解决:
- 如何存储1000位数之多的斐波那契数?
- 如何枚举?
首先,对于存储的问题,我们开辟三个数组:a[0]
,a[1]
,a[2]
,分别轮流存放两个已经求出的斐波那契数和
目前要求的斐波那契数。
对于枚举,我们选择迭代的方式,因为我们上面规定了,三个数组是轮流存放的,因此每次循环的情况会不同,如果采用迭代,我们共容易去对三个数组的存放状况做控制。
代码
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <time.h>
#define MAX_N 1000
#define max(a, b) ({\
__typeof(a) _a = a;\
__typeof(b) _b = b;\
(_a) > (_b) ? (_a) : (_b);\
})
int fib[3][MAX_N + 5];
int add_num(int *a, int *b, int *c) {
int maxbit = max(a[0], b[0]);
for (int i = 1; i <= maxbit; i++) {
c[i] = a[i] + b[i];
}
c[0] = maxbit;
for (int i = 1; i <= c[0]; i++) {
if (c[i] < 10) continue;
c[i + 1] += c[i] / 10;
c[i] %= 10;
c[0] += (c[0] == i);
}
return 1;
}
int fibf(int flag) {
switch(flag) {
case 0: {
add_num(fib[0], fib[1], fib[2]);
return fib[2][0];
}; break;
case 1: {
add_num(fib[1], fib[2], fib[0]);
return fib[0][0];
}; break;
case 2: {
add_num(fib[2], fib[0], fib[1]);
return fib[1][0];
}; break;
default: return -1;
}
}
void init() {
fib[0][0] = 1;
fib[0][1] = 1;
fib[1][0] = 1;
fib[1][1] = 1;
return ;
}
int main() {
int ans = 0;
init();
for (int i = 3; i; i++) {
if (fibf(i % 3) != 1000) continue;
ans = i;
break;
}
printf("ans = %d\n", ans);
return 0;
}