HDU 3117 Fibonacci Numbers 数论

题目地址: http://acm.hdu.edu.cn/showproblem.php?pid=3117


题意求解裴波拉挈的前四位和后四位。

前四位用取对数取小数然后指数

后四位用矩阵快速幂求解


代码如下:

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
#include <vector>
#include <set>
#include <map>
#include <queue>
using namespace std;

/*
freopen("input.txt",  "r", stdin);  //读数据
freopen("output.txt", "w", stdout); //注释掉此句则输出到控制台
*/

const double s5=sqrt(5.0);
int xh[50],n;

struct juzheng
{
    int a[2][2];
}jj[60],w,t;
int q[60];//存放n的二进制

juzheng xiaohao(juzheng a,juzheng b)
{//矩阵相乘
    t.a[0][0]=(a.a[0][0]*b.a[0][0]+a.a[0][1]*b.a[1][0])%10000;
    t.a[0][1]=(a.a[0][0]*b.a[0][1]+a.a[0][1]*b.a[1][1])%10000;
    t.a[1][0]=(a.a[1][0]*b.a[0][0]+a.a[1][1]*b.a[1][0])%10000;
    t.a[1][1]=(a.a[1][0]*b.a[0][1]+a.a[1][1]*b.a[1][1])%10000;
    return t;
}

int qian4()
{//求前4位数,和上一篇博客的求发一样
    double temp;
    temp=log10(1/s5)+n*log10((1+s5)/2);
    temp-=floor(temp);
    temp=pow(10.0,temp);
    while(temp<1000)
        temp*=10;
    return (int)temp;
}

void hou4()
{//求后4位数
    int k=n-1,i,j=1;
    while(k)
    {
        q[j++]=k%2;
        k/=2;
    }
    w.a[0][0]=w.a[0][1]=w.a[1][0]=1;
    w.a[1][1]=0;
    jj[1]=w;
    w.a[0][0]=w.a[1][1]=1;
    w.a[1][0]=w.a[0][1]=0;
    for(i=1;i<j;i++)
    {
        if(i!=1)
            jj[i]=xiaohao(jj[i-1],jj[i-1]);
        if(q[i]==0)
            continue;
        w=xiaohao(w,jj[i]);
    }
    printf("%04d\n",w.a[0][0]);//这个地方一定要输出%04d,因为可能只有三位,那么前面一位要补上0
}

int main()
{
    int i,j;
    xh[0]=0;
    xh[1]=xh[2]=1;
    for(i=3;i<=39;i++)
    {
        xh[i]=xh[i-1]+xh[i-2];
    }
    while(cin>>n)
    {
        if(n<=39)
        {//打表可知道i<=39时位数少于等于8位,直接输出
            printf("%d\n",xh[n]);
            continue;
        }
        printf("%d...",qian4());
        hou4();
    }
    return 0;
}


你可能感兴趣的:(HDU 3117 Fibonacci Numbers 数论)