Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 378 Accepted Submission(s): 184
0 1 2 3 4 5 35 36 37 38 39 40 64 65
0 1 1 2 3 5 9227465 14930352 24157817 39088169 63245986 1023...4155 1061...7723 1716...7565
/************************************************************************ 此题前四位要用到斐波那契的通项公式 Fibonacci Numbers 的通项公式: f(n)=1/sqrt(5.0)(((1+sqrt(5.0))/2)^n+((1-sqrt(5.0))/2)^n); 假设F[n]可以表示成 t * 10^k(t是一个小数),那么对于F[n]取对数log10, 答案就为log10 t + K,此时很明显log10 t<1,于是我们去除整数部分, 就得到了log10 t ,再用pow(10,log10 t)我们就还原回了t。 将t×1000就得到了F[n]的前四位。 log10(fn)=n* log10((1.0+sqrt(5.0))/2)+log10(1/sqrt(5.0)); 后四位用矩阵连乘,当然要用到快速幂了 别忘了后四位求出来可能没有四位数哦,有可能是0123这种情况 ************************************************************************/ #include <iostream> #include <math.h> using namespace std; #define N 2 #define ll __int64 #define MOD 10000 struct Mat { int martix[N][N]; }; Mat q,res,tp,tp1,tp2,tp3; int Fibonacci[40]; void er_fun(int x) { int i,j,k,flag=0; tp1=q; tp=res; while (x) { if(x&1) { flag=1; memset(tp2.martix,0,sizeof(tp2.martix)); for (i=0;i<N;i++) { for (j=0;j<N;j++) { for(k=0;k<N;k++) { tp2.martix[i][j]+=(tp.martix[i][k]*tp1.martix[k][j])%MOD; tp2.martix[i][j]%=MOD; } } } } memset(tp3.martix,0,sizeof(tp3.martix)); for (i=0;i<N;i++) { for (j=0;j<N;j++) { for(k=0;k<N;k++) { tp3.martix[i][j]+=(tp1.martix[i][k]*tp1.martix[k][j])%MOD; } } } if(flag) tp=tp2; tp1=tp3; x>>=1; } } void init() { int i; Fibonacci[0]=0; Fibonacci[1]=1; for(i=2;i<=39;i++) { Fibonacci[i]=Fibonacci[i-1]+Fibonacci[i-2]; } } int main() { int i,j; int res_back; double res_front; int n; for(i=0;i<N;i++) { for (j=0;j<N;j++) { res.martix[i][j]=(i==j); } } q.martix[0][0]=q.martix[0][1]=q.martix[1][0]=1; q.martix[1][1]=0; init(); while (scanf("%d",&n)!=EOF) { if(n<40) { printf("%d/n",Fibonacci[n]); continue; } er_fun(n-1); res_back=tp.martix[0][0]; res_front=n* log10((1.0+sqrt(5.0))/2)+log10(1/sqrt(5.0)); res_front-=(int)res_front; res_front=pow(10.0,res_front); while(res_front<1000) res_front*=10.0; printf("%d...%4.4d/n",(int)res_front,res_back); } return 0; }