uva 10236 The Fibonacci Primes

数论题、

参考了  http://blog.csdn.net/clevermike/article/details/8177450

这道题的详细分析在黑书中(221页,第2章,数学方法与常见模型)

先看代码,代码中有注释

//费波那列素数定理

//费波那列素数:若某个费波那列数和比它小的所有费波那列数互质,则称它为费波那列素数

//若a是b的倍数,则fa是fb的倍数

//所以提示我们费波那列数和它的下标有关

//从第5个费波那列书开始,某项为费波那列素数当且仅当它的项数为素数

//其中最开始两个特殊的,第3,4项fib为2,3,它们是费波那列素数

//后面的则是第5,7,11,13,17,19,23,29………………项fibs是费波那列素数

//而素数表示2,3,5,7,11…………所以为了方便处理我们将素数表前两项改为3,4



#include <cstdio>

#include <cstring>

#define N 250010

#define M 22010

bool vis[N];

int prime[M],count;

long double fib[N];



void get_prime()

{

    memset(vis,0,sizeof(vis));

    count=0;

    for(int i=2; i<=N; i++) if(!vis[i])

    {

        prime[++count]=i;

        for(int j=i*2; j<=N; j+=i)

            vis[j]=1;

    }



    prime[1]=3;  prime[2]=4;

    //将素数表的前两位改为3,4

}



void get_fib()

{

    const long double E=1e9;

    fib[1]=1;  fib[2]=1;  fib[3]=2;  fib[4]=3;

    int flag=0;

    for(int i=5; i<=N; i++) //从第5项开始构建fib

    {

        if(flag)  //说明前一项曾经降位

        {  fib[i]=fib[i-1]+fib[i-2]/10;  flag=0; }

        //为了对应计算当前项,前二项要降位再相加

        //先默认当前fib不超过9为,将flag恢复为0,

        else

            fib[i]=fib[i-1]+fib[i-2];



        if(fib[i]>E)  //已经超过9位,当前的fib要降一位

        { fib[i]/=10;  flag=1; }

    }

}

int main()

{

    get_prime();  //先筛素数

    get_fib();    //构建fib数并且处理



    int n;

    while(scanf("%d",&n)!=EOF)

        printf("%d\n",(int)fib[prime[n]]);

    return 0;

}

 

这份代码学了一个技巧就是怎么保留前面9位

 int flag=0;

    for(int i=5; i<=N; i++) //从第5项开始构建fib

    {

        if(flag)  //说明前一项曾经降位

        {  fib[i]=fib[i-1]+fib[i-2]/10;  flag=0; }

        //为了对应计算当前项,前二项要降位再相加

        //先默认当前fib不超过9为,将flag恢复为0,

        else

            fib[i]=fib[i-1]+fib[i-2];



        if(fib[i]>E)  //已经超过9位,当前的fib要降一位

        { fib[i]/=10;  flag=1; }

    }

 

你可能感兴趣的:(fibonacci)