HDU3117
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3117
题目大意:对于给定的一个数 n ,求斐波那契数F(n)。对于超过八位的数,给出首末四位即可。
解题思路:
首先,由题目给出的样例易知,当n<40,F(n)不超过八位,这部分用个循环直接打表求出即可。
当n>=40,对于后四位,我们可以用矩阵快速幂算法,利用公式:来求解,记得模10000即可。而对于前四位......这个的数学要求就有点高了......请看:
图源:http://www.cnblogs.com/WArobot/p/6810504.html
AC代码:
1 #include <iostream> 2 #include <cstring> 3 #include <algorithm> 4 #include <cmath> 5 #include <cstdio> 6 using namespace std; 7 int F1[40]; 8 void init(){ 9 F1[0]=0,F1[1]=1; 10 for(int i=2;i<40;i++){ 11 F1[i]=F1[i-1]+F1[i-2]; 12 } 13 } 14 struct Matrix{ 15 int mat[3][3]; 16 }; 17 Matrix Multiply(Matrix x,Matrix y){ 18 Matrix temp; 19 memset(temp.mat,0,sizeof(temp.mat)); 20 for(int i=0;i<2;i++) 21 for(int j=0;j<2;j++){ 22 for(int k=0;k<2;k++){ 23 temp.mat[i][j]+=(x.mat[i][k]*y.mat[k][j]%10000); 24 } 25 } 26 return temp; 27 } 28 Matrix Fast_Power(Matrix a,int n){ 29 Matrix res; 30 memset(res.mat,0,sizeof(res.mat)); 31 for(int i=0;i<2;i++) res.mat[i][i]=1; 32 while(n){ 33 if(n&1) res=Multiply(res,a); 34 n>>=1; 35 a=Multiply(a,a); 36 } 37 return res; 38 } 39 int find_head(int n){ 40 double t=-0.5*log10(5.0)+(double)n*log10((1+pow(5.0,0.5))/2); 41 t=t-floor(t); 42 double x=pow(10,t+3); 43 return (int)floor(x); 44 } 45 int main() 46 { 47 init(); 48 int n; 49 while(scanf("%d",&n)==1){ 50 if(n<40) printf("%d\n",F1[n]); 51 else{ 52 int head=find_head(n)%10000; 53 Matrix temp,ans; 54 temp.mat[0][0]=0; 55 temp.mat[0][1]=temp.mat[1][0]=temp.mat[1][1]=1; 56 ans=Fast_Power(temp,n-1); 57 int ending=ans.mat[1][1]%10000; 58 printf("%04d...%04d\n",head,ending); //%04d可以防止出现0424被打印成424 59 } 60 } 61 return 0; 62 }
“这些年我一直提醒自己一件事情,千万不要自己感动自己。大部分人看似的努力,不过是愚蠢导致的。什么熬夜看书到天亮,连续几天只睡几小时,多久没放假了,如果这些东西也值得夸耀,那么富士康流水线上任何一个人都比你努力多了。人难免天生有自怜的情绪,唯有时刻保持清醒,才能看清真正的价值在哪里。”