HDU 1568
2015-05-25 15:45
1046 查看
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1568
首先我们要知道斐波那契数列是有通项公式的。
超过4位数的斐波那契数列第n项用科学计数法表示出来,即t*10^k,t>1
由于这个数字比较大,我们用对数存下来,即log10(t)+k
然后再求出10^log10(t),乘以1000,取整,得到结果
我们需要想方设法将通项公式对数化
经过一系列证明,可以发现,当n比较大的时候时,通项公式中
是可以直接省略的,并且对最终前四位数字的输出无任何影响。
首先将省略前后的两个通项公式对数化,然后大概就是计算一个不等式,省略前的t1与省略后的t2之间的差值的绝对值<10^(-3),可以算出n似乎只要大于十几就可以了(我没有具体去算)
此外,此题有点恶心,又用了强制转换。。。
题目大意
求斐波那契数列第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; } }
相关文章推荐
- HDU 1568 Fibonacci
- HDU 1568 Fibonacci
- Fibonacii (HDU 1568)
- HDU 1568 Fibonacci(科学计数法+对数)
- HDU 1568 Fibonacci
- HDU 1568 Fibonacci
- http://acm.hdu.edu.cn/showproblem.php?pid=1568
- hdu 1568 Fibonacci
- hdu 1568 Fibonacci
- HDU 1568 Fibonacci (取对数)
- HDU 1568
- hdu 1568 Fibonacci
- 数论(fabonacci数列) hdu-1568-Fibonacci
- HDU-1568-Fibonacci【求高位数字】
- HDU 1568 Fibonacci
- hdu 1568
- HDU 1568
- HDU 1568 Fibonacci
- hdu 1568 Fibonacci
- [斐波那契前n位 数学技巧] HDU 1568 Fibonacci