zoukankan      html  css  js  c++  java
  • 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
    ",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
    ",head,ending);  //%04d可以防止出现0424被打印成424
    59         }
    60     }
    61     return 0;
    62 }
    “这些年我一直提醒自己一件事情,千万不要自己感动自己。大部分人看似的努力,不过是愚蠢导致的。什么熬夜看书到天亮,连续几天只睡几小时,多久没放假了,如果这些东西也值得夸耀,那么富士康流水线上任何一个人都比你努力多了。人难免天生有自怜的情绪,唯有时刻保持清醒,才能看清真正的价值在哪里。”
  • 相关阅读:
    聚集索引
    第一天 尝试Thread
    sql 分区函数
    sql 查询表定义
    千万数量级分页存储过程
    成语解释
    sql 分组查询满足条件所以数据
    sql存储过程
    联表更新的反思
    从表保存了主表的id,以分号分隔,怎么样用一条sql搞定主表满足条件的查询? 不希望单独写存储过程,或者后台拆成int后传进来,就一条sql 搞定,一条
  • 原文地址:https://www.cnblogs.com/Blogggggg/p/7356668.html
Copyright © 2011-2022 走看看