城市的规划在城市建设中是个大问题。
不幸的是,很多城市在开始建设的时候并没有很好的规划,城市规模扩大之后规划不合理的问题就开始显现。
而这座名为 Fractal 的城市设想了这样的一个规划方案,如下图所示:
当城区规模扩大之后,Fractal 的解决方案是把和原来城区结构一样的区域按照图中的方式建设在城市周围,提升城市的等级。
对于任意等级的城市,我们把正方形街区从左上角开始按照道路标号。
虽然这个方案很烂,Fractal 规划部门的人员还是想知道,如果城市发展到了等级 NN,编号为 AA 和 BB 的两个街区的直线距离是多少。
街区的距离指的是街区的中心点之间的距离,每个街区都是边长为 1010 米的正方形。
输入格式
第一行输入正整数 nn,表示测试数据的数目。
以下 nn 行,输入 nn 组测试数据,每组一行。
每组数据包括三个整数 N,A,BN,A,B,表示城市等级以及两个街区的编号,整数之间用空格隔开。
输出格式
一共输出 nn 行数据,每行对应一组测试数据的输出结果,结果四舍五入到整数。
数据范围
1≤N≤311≤N≤31,
1≤A,B≤22N1≤A,B≤22N,
1≤n≤10001≤n≤1000
输入样例:
3
1 1 2
2 16 1
3 4 33
输出样例:
10
30
50
代码
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
typedef long long ll;
typedef pair<ll,ll> pll;
pll calc(ll n,ll m) // 由低阶开始推,每往外多一层都要转换一次。
{
if(n==0) return make_pair(0,0);
ll len=1ll<<n-1,cnt=1ll<<2*n-2;//前者是子矩阵的长,后者是子矩阵的房子总数。
pll pos=calc(n-1,m%cnt);//递归求子矩阵的中的坐标
ll x=pos.first,y=pos.second;
ll z=m/cnt;
//计算是由0开始的,但是题上是由1开始,所以在函数传参数的时候需要减一
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); //右下角
return make_pair(2*len-1-y,len-1-x); //左下角
}
int main()
{
ll T;
cin>>T;
while(T--)
{
ll n,a,b;
cin>>n>>a>>b;
pll ac=calc(n,a-1);//找到对应的坐标
pll bc=calc(n,b-1);
double x=ac.first-bc.first,y=ac.second-bc.second;
printf("%.0lf\n",sqrt(x*x+y*y)*10);//求两点之间的距离
}
return 0;
}