AOJ-AHU-OJ-401 Fibonacci & GCD

来源:互联网 发布:js有几种数据类型 编辑:程序博客网 时间:2024/06/05 10:05
Fibonacci & GCD
Time Limit: 1000 ms   Case Time Limit: 1000 ms   Memory Limit: 64 MB
 
Description
Fibonacci数列之所以强大是因为它可以和很多东西结合,这次Fibonacci找来了GCD(最大公约数)来和自己组合,这给我们带来的问题是对于Fibonacci数列中的任意两项F(m)和F(n),我们要求出它们的最大公约数

 

Input
输入包括多组测试数据,每行包括2个正整数m,n( 1 =< m,n =< 10^9)表示Fibonacci的第m,n项,输入以 0 0 结束

 

Output
每组输入对应一个输出即 GCD( F(m) , F(n) ),因为结果可能比较大,输出其 mod 10003的值

 

Sample Input
OriginalTransformed
4 80 0

 

Sample Output
OriginalTransformed
3

 

Source
Large的高精度 NO.4
 
——————————————————————分割线——————————————————————
 
思路:本题牵扯到斐波那契的两个定理。一个是斐波那契作为初等函数,尾数具有循环性,要找到循环节。利用循环节,来极大地缩小需要存储数据的数组大小。即优化空间。所谓循环节,就是从第i项和第i+1项开始尾数变成0和1。
另一个是最大公约数(GCD)定理。GCD( fib[n], fib[m] ) == fib[ GCD(n, m) ]。
 
代码如下:

#include <stdio.h>int fib[5711];int GCD(int a, int b){    if(!b)      return a;    return GCD(b, a % b);}int main(){    int m, n, g;    int i;    fib[0] = 1;    fib[1] = 1;    for(i = 2;;i++){        fib[i] = (fib[i-1] + fib[i-2]) % 10003;        if(fib[i-1] == 0&&fib[i] == 1)        break;    }    i--;    while(scanf("%d%d", &m, &n) != EOF&&m||n){        g = GCD(m, n);        g--;        printf("%d\n", fib[g%i]);    }    return 0;}

 

0 0