/*
关键在于:求编号为M的房屋 在N级城市中的位置 calc(N,M)
基于此求distance(calc(N,S),calc(N,D))
可以看出 N级城市由4座N-1级城市组成
左上角的N-1级城市顺时针旋转90°
同时 左上角的编号发生"水平翻转"
逆时针转b°
x' = r cos(a + b) = r cos(a)cos(b) – r sin(a)sin(b) (1.1)
y' = r sin(a + b) = r sin(a)cos(b) + r cos(a) sin(b) (1.2)
其中x = r cos(a) , y = r sin(a)
x' = x cos(b) – y sin(b) (1.3)
y' = x sin(b) + y cos(b) (1.4)
以十字中心为原点来分析
逆时针转 b = 90 时 (x',y') = (-y,x)
1(0,0)->(-1,1)(新坐标系)
counter_rot(90)1(-1,1) = (-1,-1)
顺时针转90°==逆时针转 b = 270时 (x',y') = (y,-x)
rot(90)1(-1,1) = (1,1)
但是在这里我们的原点坐标在左上角 那么-x 就 体现为 -x + 2^(N-1)-1
直观一点
-x就体现为关于(恒正数)对称轴的对称->从坐标长度的最大值-x =2^(N-1)-1 - x
o | o
--.--
o | o
以N=2 为例 假如原来x = 0 x'=-x(以十字中心为原点)=-x + 2^(N-1)-1(以左上角为原点+边长-1)
解释为什么要-1 因为我们的坐标不是以1开始 而是以0开始 所以末尾的索引=长度-1
所以涉及到负的去做操作的时候 坐标都要-1
. o o o o . o o
o o o o -> o o o o
o o o o o o o o
o o o o o o o o
顺时针转 编号翻转
1-2 4 1 1 4
| -> | | -> | |
4-3 3-2 2-3
左下角的N-1级城市逆时针旋转90°
同左上角 左下角的编号也发生了水平翻转
逆时针转 编号翻转
13-14 14-15 15-14
| -> | | -> | |
16-15 13 16 16 13
2^(N-1)为第一级城市的边长
1 处于左上角
顺90° 翻转
(x,y)->(y,2^(N-1)-x-1)->(y,x)
2 处于右上角 城市列号+2^(N-1)
以 0 1 2 3 为例 2,3就是0+2^1 和1+2^1
(x,y)->(x,y+2^(N-1))
3 处于右下角 城市列号+2^(N-1)
(x,y)->(x+2^(N-1),y+2^(N-1))
4 处于左下角
逆90°
x' = 2^(N-1)-y-1
y' = x
翻转(行不变,列关于对称轴对称->2^(N-1)-1-y')
x'' = x' = 2^(N-1)-y-1
y'' = 2^(N-1)-1-y' = 2^(N-1)-x-1
逆90° 翻转(列作对称) 位于第三象限 N级城市行号+2^(N-1)
(x,y)->(2^(N-1)-y-1,x)->(2^(N-1)-y-1,2^(N-1)-x-1)->(2^(N)-y-1,2^(N-1)-x-1)
*/
#include <cstdio>
#include <cstring>
#include <cmath>
typedef long long LL;
struct Point
{
LL x, y;
};
Point calc(LL n, LL a)
{
if (n == 0) return {0, 0};
LL cnt = 1ll << (n * 2 - 2), len = 1ll << (n - 1);//N-1级城市共有cnt=2^(n * 2 - 2)座房屋
auto p = calc(n - 1, a % cnt);//a % cnt就是 该编号在更低N-1级城市里所属的4座城市的哪一座
// 以 13 % 4 = 1 则 13是子城市的第一座城市
// 13-14
// |
// 16-15
LL x = p.x, y = p.y;//在子城市里的坐标
int z = a / cnt;//当前序号除子城市数 = 第几个子城市
// 0~16 子城市=4 以13为例 13/4 = 3 则它在左下角
if (z == 0) return {y, x};//0~4 左上角
else if (z == 1) return {x, y + len};//4~8 右上角
else if (z == 2) return {x + len, y + len};// 9~12 右下角
return {len * 2 - 1 - y, len - 1 - x};//13~16 左下角
}
int main()
{
int T;
scanf("%d", &T);
while (T -- )
{
LL n, a, b;
scanf("%lld%lld%lld", &n, &a, &b);
auto pa = calc(n, a - 1);
auto pb = calc(n, b - 1);
double dx = pa.x - pb.x, dy = pa.y - pb.y;
printf("%.0lf\n", sqrt(dx * dx + dy * dy) * 10);
}
return 0;
}