分形之城 

(fra.pas/c/cpp)

题目描述

城市的规划在城市建设中是个大问题。不幸的是,很多城市在开始建设的时候并没有很好的

规划,城市规模扩大之后规划不合理的问题就开始显现。而这座名为Fractal 的城市设想了

这样的一个规划方案,如下图所示:

当城区规模扩大之后,Fractal 的解决方案是把和原来城区结构一样的区域按照图中的方式

建设在城市周围,提升城市的等级。对于任意等级的城市,我们把正方形街区从左上角开

始按照道路标号。虽然这个方案很烂,Fractal 规划部门的人员还是想知道,如果城市发展

到了等级N,编号为A 和B 的两个街区的直线距离是多少。街区的距离指的是街区的中心

点之间的距离,每个街区都是边长为10 米的正方形。

输入格式

输入文件包含多组测试数据,第一行有一个整数T 表示测试数据的数目。

每组测试数据包含一行三个整数 N, A, B,表示城市等级以及两个街区的编号。

输出格式

对于每组测试数据,在单独的一行内输出答案,四舍五入到整数。

样例输入

3

1 1 2

2 16 1

3 4 33

样例输出

10

30

50

数据范围与约定

对于30% 的数据,N≤5,T≤10。

对于 100% 的数据,N≤31,1≤A,B≤22N。T≤1000。

 

对于这道题,显然,范围太大,我们要根据图来一步步缩小范围,算是分治/递归?吧

但是,图翻来覆去的(*-*)+_+

咋办?

大神说有公式,有规律,可是,身为蒟蒻的我不会。。。。。。

Orz

难道放弃?不!

我们可以发现,最多也只有4种规则,而每一种规则将图化为4部分,每一个部分又对应另一种规则(确定的),那么,最多一共有4*4=16种规则方式

然后,。。。。。。。打表(别说我无耻)

program ex03;
const ne:array[0..3,0..3] of longint=((1,0,2,0),  //对应关系
                                      (0,3,1,1),
                                      (2,2,0,3),
                                      (3,1,3,2));
      ch:array[0..3,0..3] of longint=((0,1,3,2), //放置规则
                                      (0,2,3,1),
                                      (3,1,0,2),
                                      (3,2,0,1));
var n,a,b:qword;
    t,i:longint;
function qm(a,b:qword):qword;
var t,sum:qword; i:longint;
begin
  sum:=1;
  for i:=1 to b do
   sum:=sum*a;
  exit(sum);
end;
procedure init;
begin
  readln(n,a,b);
  a:=a-1; b:=b-1;
end;
procedure find(a,p:qword; q:double; k:qword; var x,y:double);   //一直缩小范围
var i:qword;
begin
  i:=a div p;                                       //放置规则
  if ch[k][i]=0 then begin x:=x-q; y:=y-q; end else
  if ch[k][i]=1 then begin x:=x-q; y:=y+q; end else
  if ch[k][i]=2 then begin x:=x+q; y:=y-q; end else
  if ch[k][i]=3 then begin x:=x+q; y:=y+q; end;
  k:=ne[k][ch[k][i]];   //下一个要选哪个策略
  if p=1 then exit;
  a:=a mod p;
  find(a,p div 4,q/2,k,x,y);
end;
procedure doit;
var p,q:qword;
    xa,ya,xb,yb,o:double;
    s,x,y:double;
begin
  p:=qm(4,n-1);                                  //不要用快速幂;我是炸了无数次后才改的循环,其实时间差不多  
  q:=qm(2,n-1);
  o:=q;
  xa:=q; ya:=q; xb:=q; yb:=q;
  find(a,p,o/2,0,xa,ya);
  find(b,p,o/2,0,xb,yb);
  s:=sqrt(sqr(ya-yb)+sqr(xa-xb));
  writeln(trunc(s*10+0.5));                      //注意,一定要最后*10,不然会炸;
end;

begin
  assign(input,'fra.in'); reset(input);
  assign(output,'fra.out'); rewrite(output);
  readln(t);
  for i:=1 to t do
  begin
    init;
    doit;
  end;
  close(input);
  close(output);
end.

 

posted on 2016-11-03 20:07  艾路雷朵  阅读(559)  评论(0编辑  收藏  举报