【Nov 8 P3,斐波那契】古代人的难题
【题目描述】
门打开了,里面果然是个很大的厅堂。但可惜厅堂内除了中央的一张羊皮纸和一根精致的石笔,还有周围几具骷髅外什么也没有。难道这就是王室的遗产?小 FF不信,他仔细阅读了羊皮纸上的内容后发现,里面书写的古代人一直没能解出的难题,解除这道题目的人只要将答案用石笔写到这张羊皮纸上就能到达王室的宝藏室了。而当小FF拿起石笔后,刚刚打开的巨石门突然关上了。这时小 FF意识到原来那几具骷髅是在他之前到这里的冒险者,恐怕是因为没能破解这道题而困死在这里了。小FF越想越害怕,急忙联系到了你,为了能保命,他甚至愿意和你五五分……看来你不得不再次帮他了。羊皮纸上的问题如下:已知 x, y为整数,且满足以下两个条件:
1. x, y ∈[1..k],且 x,y,k ∈Z;2.(x^2 –xy – y^2)^2 =1
给你一个整数 k,求一组满足上述条件的x, y并且使得 x^2 +y^2的值最大。当小FF得到答案后,用石笔将答案书写在羊皮纸上,那么就能到达王室的遗产所在地了。
【输入格式】
一个整数 k
【输出格式】
输出文件仅一行,两个整数;两个整数分别表示 x和 y。x, y之间用一个空格隔开。
【输入样例】
1995
【输出样例】
1597 987
【数据范围】
对于 30%的数据: 2<=k<=10^4.
对于 100%的数据: 2<=k<=10^18.
初看本题,真的是无从下手。1018的数据量枚举肯定爆。所以我们首先用小数据打表,根据前几个值看有没有规律。
参考代码(Make):
program make; var i,j:longint; k1,k2,k3:int64; begin for i:=1 to 1000000 do for j:=1 to i do begin k1:=(i*j+1)div(i+j); k2:=(i*j-1)div(i+j); if(i*j+1)mod(i+j)=0 then if i-j=k1 then writeln(i,' ',j); if(i*j-1)mod(i+j)=0 then if i-j=k2 then writeln(i,' ',j); end; end.
上面代码是对经过化简的等式进行处理的,用原等式也可以。
这样,我们得到一列数对:
1 1
2 1
3 2
5 3
8 5
13 8
21 13
34 21
55 34
89 55
144 89
233 144
377 233
610 377
987 610
1597 987
2584 1597
4181 2584
6765 4181
10946 6765
17711 10946
28657 17711
简单分析后我们发现,这两列数竟然分别符合斐波那契数列的规律!
这样,我们就可以依次找到斐波那契数列的前几项i-1,直到第i项大于k。这时我们只要输出i-1项和i-2项就可以了。
在数列处理方面,我选择了打表,其实依次求的时间也可以承受,毕竟斐波那契数列的增长很迅速。
参考代码:
program puzzle; const a:array[1..88]of int64=(斐波那契数列); var n:int64; i,p:integer; begin readln(n); for i:=1 to 88 do if a[i]>n then begin p:=i; break; end; writeln(a[p-1],' ',a[p-2]); end.
本文地址:http://www.cnblogs.com/saltless/archive/2010/11/10/1873234.html
(saltless原创,转载请注明出处)