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 }

 

posted @ 2017-08-14 11:03  Blogggggg  阅读(481)  评论(1编辑  收藏  举报