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