zoukankan      html  css  js  c++  java
  • hdu1568&&hdu3117 求斐波那契数前四位和后四位

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1568

    题意:如标题所示,求斐波那契数前四位,不足四位直接输出答案

    斐波那契数列通式:

    当n<=20的时候,不足四位,所以直接打表。

    当n>20的时候,大于四位的时候,ans满足这个公式:ans=-0.5*log10(5.0)+num*1.0*log10((1+sqrt(5.0))/2.0);                                                                                                                                                        

    这个公式是怎么来的呢?我们可以对an取10的对数,根据对数的性质。                                                                                                                                                                                                                        

    log10(ans)=log10(1/sqrt(5))+log10(((1+sqrt(5))/2)^num-((1-sqrt(5))/2)^num))                                                                                                                                                                                            

    log10(ans)=0-0.5*log10(5.0)+log10(((1+sqrt(5))/2)^num-((1-sqrt(5))/2)^num)),当num趋于无穷的的时候  。

    lim((1-sqrt(5))/2)^num)=0                                                                                                              

    log10(ans)=0-0.5*log10(5.0)+log10(((1+sqrt(5))/2)^num)= -0.5*log10(5.0)+num*1.0*log10( (1+sqrt(5))/2),我们就得到了上文的公式。                                                                                                          

    这里说一下原理,x=123456789,那么y=log10(x)=1.23456789,这个时候将y*=1000,就得到了 y=1234.56789,求幂次和取对数互为逆运算,通过这个原理我们可以求前x的长度。   

    //Author: xiaowuga
    #include <bits/stdc++.h>
    #define maxx INT_MAX
    #define minn INT_MIN
    #define inf 0x3f3f3f3f
    #define maxn 
    using namespace std;
    typedef long long ll;
    ll table[21];
    int main() {
        ios::sync_with_stdio(false);cin.tie(0);
        table[0]=0;table[1]=1;
        for(int i=2;i<=20;i++) table[i]=table[i-1]+table[i-2];
        ll num;
        while(cin>>num){
           if(num<=20) cout<<table[num]<<endl;
            else{
                double ans=-0.5*log10(5.0)+num*1.0*log10((1+sqrt(5.0))/2.0);
                ans=ans-(ll)ans;
                double a=pow(10.0,ans);
                a=1000*a;
                cout<<(ll)a<<endl;
            } 
        } 
        return 0;
    }

    hdu3117:Fibonacci Numbers

    这道题求斐波那契的数列的前四位和后四位,前四位和1568是一样的,后四位只需要把mod变成10000就行了,比较简单,直接看代码吧!!

    //Author: xiaowuga
    #include <bits/stdc++.h>
    #define maxx INT_MAX
    #define minn INT_MIN
    #define inf 0x3f3f3f3f
    #define n 2
    #define MOD 10000
    using namespace std;
    typedef long long ll;
    ll table[45];
    ll first_four(ll num){
         double ans=-0.5*log10(5.0)+num*1.0*log10((1+sqrt(5.0))/2.0);
         ans=ans-(ll)ans;
         double a=pow(10.0,ans);
         a=1000*a;
         return (ll)a;
    }
    struct Matrix{
        ll mat[2][2];
        Matrix operator * (const Matrix & m) const{
            Matrix tmp;
            for(int i=0;i<n;i++)
                for(int j=0;j<n;j++){
                    tmp.mat[i][j]=0;
                    for(int k=0;k<n;k++){
                        tmp.mat[i][j]+=mat[i][k]*m.mat[k][j]%MOD;
                        tmp.mat[i][j]%=MOD;
                    }
                }
            return tmp;
        }
    };
    Matrix POW(Matrix &m,ll k){
        Matrix ans;
        memset(ans.mat,0,sizeof(ans.mat));
        for(int i=0;i<n;i++) ans.mat[i][i]=1;
        while(k){
            if(k&1) ans=ans*m;
            k/=2;
            m=m*m;
        }
        return ans;
    }
    int main() {
        ios::sync_with_stdio(false);cin.tie(0);
        table[0]=0;table[1]=1;
        for(int i=2;i<=39;i++) table[i]=table[i-1]+table[i-2];
        ll num;
        while(cin>>num){
           if(num<=39) cout<<table[num]<<endl;
           else{
                cout<<first_four(num)<<"...";
                Matrix m;
                memset(m.mat,0,sizeof(m.mat));
                m.mat[0][1]=m.mat[1][1]=m.mat[1][0]=1;m.mat[0][0]=0;
                Matrix ans=POW(m,num-1);
                cout.fill('0');
                cout.width(4);
                cout<<ans.mat[1][1]%MOD<<endl;
           }
        } 
        return 0;
    }
  • 相关阅读:
    Ubuntu 16.04 not a com32r image
    重定向输出遇到的缓冲问题
    you don't have permission to access / on this server解决
    LaTeX入门简介
    解决eclipse中出现Resource is out of sync with the file system问题
    Ubuntu安装新英伟达驱动出现问题解决方法
    同步与异步的区别
    Cuda入门笔记
    解决 Cocos2d-x 3.2 error C1041: 无法打开程序数据库vc120.pdb
    vs2013编译过程中,错误 59 error C4996: 'GetVersionExW': 被声明为已否决
  • 原文地址:https://www.cnblogs.com/xiaowuga/p/7169470.html
Copyright © 2011-2022 走看看