【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原创,转载请注明出处)

 

posted on 2010-11-10 06:55  saltless  阅读(575)  评论(0编辑  收藏  举报

导航