wyh123
解题思路记录和牢骚
C++博客
|
首页
|
发新随笔
|
发新文章
|
联系
|
聚合
|
管理
随笔:34 文章:1 评论:1 引用:0
HDOJ 1568(Fibonacci)
题目大意:2007年到来了。经过2006年一年的修炼,数学神童zouyu终于把0到100000000的Fibonacci数列(f[0]=0,f[1]=1;f[i]=f[i-1]+f[i-2](i>=2))的值全部给背了下来。
接下来,CodeStar决定要考考他,于是每问他一个数字,他就要把答案说出来,不过有的数字太长了。所以规定超过4位的只要说出前4位就可以了,可是CodeStar自己又记不住。于是他决定编写一个程序来测验zouyu说的是否正确。
解决方法:首先,要知道斐波那契数列的通项公式:
F(n)=(1/√5)*{[(1+√5)/2]^n - [(1-√5)/2]^n}
接着,化简,在n足够大的时候,可以省去后面【(1-sqrt(5))/2】^n。
那么式子就可以化为:
An=1/sqrt(5)*[(1+sqrt(5))/2]^n;
但题目要求的是An的前4位,而显然按照上面的公式,很快也就会超出int的范围,那么只能通过去对数来降低其长度。
对等式两边取对数有: lgAn=n*lg((1+sqrt(5.0))*0.5)-0.5*lg(5.0);
这里选取log10的原因是lg(n*10^m)=lg(n)+m; 而10^n就是答案mod 10^m,所以,我们只要将10^n乘到>1000即刻取出前4位
1
#include
<
iostream
>
2
#include
<
cmath
>
3
using
namespace
std;
4
int
main()
5
{
int
fib[
21
],i,n;
6
fib[
0
]
=
0
;fib[
1
]
=
1
;
7
for
(i
=
2
;i
<
21
;i
++
)
8
fib[i]
=
fib[i
-
1
]
+
fib[i
-
2
];
9
10
while
(scanf(
"
%d
"
,
&
n)
!=
EOF)
11
{
12
if
(n
<=
20
)
13
printf(
"
%d\n
"
,fib[n]);
14
else
15
{
double
p
=
n
*
log10((
1
+
sqrt(
5.0
))
*
0.5
)
-
0.5
*
log10(
5.0
);
16
p
=
p
-
int
(p);
17
int
res
=
pow(
10.0
,p)
*
1000
;
18
printf(
"
%d\n
"
,res);
19
}
20
}
21
return
0
;
22
}
23
。
发表于 2011-07-29 11:20
wyh
阅读(404)
评论(0)
编辑
收藏
引用
只有注册用户
登录
后才能发表评论。
【推荐】100%开源!大型工业跨平台软件C++源码提供,建模,组态!
网站导航:
博客园
IT新闻
BlogJava
博问
Chat2DB
管理
<
2011年7月
>
日
一
二
三
四
五
六
26
27
28
29
30
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
1
2
3
4
5
6
常用链接
我的随笔
我的评论
我参与的随笔
留言簿
给我留言
查看公开留言
查看私人留言
随笔分类
DP(8)
(rss)
比赛总结
(rss)
博弈
(rss)
二分
(rss)
模拟(3)
(rss)
数据结构
(rss)
数学(19)
(rss)
搜索(1)
(rss)
随笔档案
2011年8月 (19)
2011年7月 (15)
文章分类
DP
(rss)
模拟
(rss)
数据结构
(rss)
数论(1)
(rss)
搜索
(rss)
图论
(rss)
文章档案
2011年7月 (1)
搜索
最新评论
1. re: HDOJ 2067(DP)
压根就没有看懂题意的路过~~!
--wgh
阅读排行榜
1. poj 1015(DP)(1030)
2. HDOJ 2563(递推)(845)
3. poj 1029(模拟)(777)
4. HDOJ 1286(欧拉函数)(661)
5. poj 1042(DP)(653)
评论排行榜
1. HDOJ 2067(DP)(1)
2. HDOJ 2041(DP)(0)
3. 2011/7/31(0)
4. HDOJ 2044(DP)(0)
5. HDOJ 2563(递推)(0)