标签:des style blog http color io os ar java
题目意思很简单:求第n个Fibonacci数,如果超过八位输出前四位和后四位中间输出...,否则直接输出Fibonacci数是多少。
后四位很好求,直接矩阵加速递推对10000取余的结果就是。
前四位搜了一下:http://blog.csdn.net/xieqinghuang/article/details/7789908
Fibonacci的通项公式,对,fibonacci数是有通项公式的——
f(n)=1/sqrt(5)(((1+sqrt(5))/2)^n+((1-sqrt(5))/2)^n)
假设F[n]可以表示成 t * 10^k(t是一个小数),那么对于F[n]取对数log10,答案就为log10 t + K,此时很明显log10 t<1,于是我们去除整数部分,就得到了log10 t ,
再用pow(10,log10 t)我们就还原回了t。将t×1000就得到了F[n]的前四位。 具体实现的时候Log10 F[n]约等于((1+sqrt(5))/2)^n/sqrt(5),这里我们把((1-sqrt(5))/2)^n这一项忽略了,
因为当N>=40时,这个数已经小的可以忽略。于是log10 F[n]就可以化简成log10 1/sqrt(5) + n*log10 (1+sqrt(5))/2
还有就是其实后四位存在一个循环节没15000个会重复一次。
0 1 2 3 4 5 35 36 37 38 39 40 64 65
0 1 1 2 3 5 9227465 14930352 24157817 39088169 63245986 1023...4155 1061...7723 1716...7565
#include <algorithm>
#include <iostream>
#include <stdlib.h>
#include <string.h>
#include <iomanip>
#include <stdio.h>
#include <string>
#include <queue>
#include <cmath>
#include <stack>
#include <map>
#include <set>
#define eps 1e-10
///#define M 1000100
#define LL __int64
///#define LL long long
///#define INF 0x7ffffff
#define INF 0x3f3f3f3f
#define PI 3.1415926535898
#define zero(x) ((fabs(x)<eps)?0:x)
///#define mod 9973
int mod;
const int maxn = 2010;
using namespace std;
struct matrix
{
int f[110][110];
};
matrix mul(matrix a, matrix b, int n)///矩阵乘法
{
matrix c;
memset(c.f, 0, sizeof(c.f));
for(int i = 0; i < n; i++)
{
for(int j = 0; j < n; j++)
{
for(int k = 0; k < n; k++) c.f[i][j] += a.f[i][k]*b.f[k][j];
c.f[i][j] %= mod;
}
}
return c;
}
matrix pow_mod(matrix a, int b, int n)///矩阵快速幂
{
matrix s;
memset(s.f, 0 , sizeof(s.f));
for(int i = 0; i < n; i++) s.f[i][i] = 1;
while(b)
{
if(b&1) s = mul(s, a, n);
a = mul(a, a, n);
b >>= 1;
}
return s;
}
matrix Add(matrix a,matrix b, int n) ///矩阵加法
{
matrix c;
for(int i = 0; i < n; i++)
{
for(int j = 0; j < n; j++)
{
c.f[i][j] = a.f[i][j]+b.f[i][j];
c.f[i][j] %= mod;
}
}
return c;
}
LL num[maxn];
int main()
{
num[0] = 0LL;
num[1] = 1LL;
for(int i = 2; i <= 40; i++) num[i] = num[i-1]+num[i-2];
mod = 10000;
int n;
while(cin >>n)
{
if(n < 40)
{
cout<<num[n]<<endl;
continue;
}
double ans;
ans = -0.5*(log10(5.0))+n*log10((sqrt(5.0)+1.0)/2);
ans -= (int)ans;
ans = pow(10, ans);
while(ans < 1000) ans *= 10;
printf("%d",(int)ans);
cout<<"...";
matrix c;
memset(c.f, 0, sizeof(c.f));
c.f[0][0] = 1;
c.f[0][1] = 1;
c.f[1][0] = 1;
matrix d;
d = pow_mod(c, n-2, 2);
int sum = 0;
sum += d.f[0][0] + d.f[0][1];
sum %= mod;
if(sum < 10) cout<<"000";
else if(sum < 100) cout<<"00";
else if(sum < 1000) cout<<"0";
cout<<sum<<endl;
}
return 0;
}
HDU 3117 Fibonacci Numbers(Fibonacci矩阵加速递推+公式)
标签:des style blog http color io os ar java
原文地址:http://blog.csdn.net/xu12110501127/article/details/39666717