• 分形之城


    分形之城 

    (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.
  • 相关阅读:
    【算法】数据结构与算法基础总览(上)数据结构篇
    Hangfire只允许同时运行同一个任务
    Redis缓存系列--(六)缓存和数据库一致性更新原则
    Redis缓存系列--(五)自定义Redis缓存注解的使用
    Redis缓存系列--(四)Redis基础数据类型在Java中的使用
    Redis缓存系列--(三)redis内存管理
    Redis缓存系列--(二)Redis持久化机制
    Redis缓存系列--(一)Redis的编译安装以及服务的开启
    深入理解Java虚拟机--垃圾收集器与内存分配策略
    分布式系统系列--(四)LVS基础知识点介绍
  • 原文地址:https://www.cnblogs.com/fengjunjie/p/6028038.html
Copyright © 2020-2023  润新知