您的位置:首页 > 编程语言 > C语言/C++

HDU 1568

2015-05-25 15:45 1046 查看
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1568

题目大意

求斐波那契数列第n项的前四位。n最大10^8

解题思路

这道题一开始没想出来,网上搜索得知取对数后我开始了我艰辛的推导过程。
首先我们要知道斐波那契数列是有通项公式的。



超过4位数的斐波那契数列第n项用科学计数法表示出来,即t*10^k,t>1
由于这个数字比较大,我们用对数存下来,即log10(t)+k
然后再求出10^log10(t),乘以1000,取整,得到结果
我们需要想方设法将通项公式对数化
经过一系列证明,可以发现,当n比较大的时候时,通项公式中

是可以直接省略的,并且对最终前四位数字的输出无任何影响。
首先将省略前后的两个通项公式对数化,然后大概就是计算一个不等式,省略前的t1与省略后的t2之间的差值的绝对值<10^(-3),可以算出n似乎只要大于十几就可以了(我没有具体去算)
此外,此题有点恶心,又用了强制转换。。。

Code

#define up(i, j, k) for(int i = j; i <= k; ++i)
#define down(i, j, k) for(int i = j; i <= k; ++i)
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <cmath>
#include <algorithm>
#include <climits>
#include <cstring>
#include <string>
#include <iomanip>

using namespace std;

int f[21];

int main()
{
ios_base::sync_with_stdio(false);
f[0]=0;
f[1]=1;
up(i,2,20) f[i]=f[i-1]+f[i-2];
int n;
while(cin>>n)
{
if (n<=20)
{
cout<<f
<<endl;
continue;
}
double a=(1+double(sqrt(5)))/2;
double res=n*log10(a)+log10(double(1/sqrt(5)));
double ans=pow(10,res-floor(res))*1000;
cout<<floor(ans)<<endl;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  acm 数学数论 c++ hdu