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; }
    }

 

posted @ 2013-01-23 18:49  Titanium  阅读(549)  评论(0编辑  收藏  举报