题意:随着越来越大的城市对现代化的不断增长的需求,人们需要新的街道设计。克里斯是负责这些设计的不幸城市规划者之一。每年的需求都在不断增加,今年他甚至被要求设计一个全新的城市。克里斯现在需要做更多的工作,因为像任何好官僚一样,他非常懒惰。鉴于这是他与大多数计算机科学家共同的性格特征,他的一个最亲密的朋友保罗实际上是计算机科学家也就不足为奇了。正是保罗提出了一个让克里斯成为同龄人英雄的好主意:分形街!通过使用希尔伯特曲线,他可以轻松填充任意大小的矩形图,只需很少的工作。 1阶的希尔伯特曲线由一个“杯”组成。在2阶Hilbert曲线中,杯子由四个较小但相同的杯子和三个连接道路代替。在3阶Hilbert曲线中,这四个杯子又被四个相同但更小的杯子和三个连接道路等替换。在杯子的每个角落,一个车道(带有邮箱)被放置用于房屋,具有简单的连续性编号。左上角的房子是1号,两个相邻房子之间的距离是10米。 图2显示了这种情况。正如您所看到的,Fractal Streets概念成功地消除了对无聊街道网格的需求,同时仍然需要我们的官僚们付出很少的努力。 为了表达他们的感激之情,几位市长为克里斯提供了一个房子,这个房子位于用他自己的新计划建造的许多新街区之一。克里斯现在想知道哪些产品会让他最接近当地城市规划办公室(当然这些新社区中的每一个都有一个)。幸运的是,他不必在街上开车,因为他的新公司“汽车”就是那些新的飞行汽车之一。这种高科技车辆允许他从他的车道直线行驶到他新办公室的车道。你能编写一个程序来确定每个飞行员必须飞行的距离(不包括起飞和着陆时的垂直距离)吗?
分析:
//#include<bits/stdc++.h>
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
inline int read(){
int x=0,o=1;char ch=getchar();
while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
if(ch=='-')o=-1,ch=getchar();
while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
return x*o;
}
inline pair<int,int> calc(int n,int m){
if(!n)return make_pair(0,0);
int len=1<<(n-1),cnt=1<<(2*n-2);
pair<int,int>pos=calc(n-1,m%cnt);
int x=pos.first,y=pos.second,z=m/cnt;
if(z==0)return make_pair(y,x);
if(z==1)return make_pair(x,y+len);
if(z==2)return make_pair(x+len,y+len);
if(z==3)return make_pair(2*len-y-1,len-x-1);
}
inline double pf(int x){return 1.0*x*x;}
int main(){
int T=read();
while(T--){
int n=read(),x=read(),y=read();--x;--y;
pair<int,int>a=calc(n,x),b=calc(n,y);
double ans=sqrt(pf(a.first-b.first)+pf(a.second-b.second))*10.0;
printf("%.0lf\n",ans);
}
return 0;
}