1.sqrt(tmp)*10 防止sqrt溢出
2.旋转矩阵(逆时针):
cos -sin * x0 = x
sin cos y0 y
3.以原点为中心旋转后直接平移即可
4.到处都有精度问题
#include<cstdio>
#include<iostream>
#include<cmath>
#define ll long long
using namespace std;
ll ksm(ll a,ll x){
ll sum=1;
while(x){
if(x&1){
sum=sum*a;
}
a=a*a;
x>>=1;
}
return sum;
}
const int MAXN=1000;
struct Point{
ll x,y;
}p[MAXN];
//左上
/**
* @n 转移后的层数
*/
Point getOne(ll x0,ll y0,int n){
ll a=2,b=n;
Point point=Point{y0,-x0+1+ksm(a,b)};
return point;
}
//右上
Point getTwo(ll x0,ll y0,int n){
ll a=2,b=n-1;
Point point=Point{x0+ksm(2,n-1),y0+ksm(a,b)};
return point;
}
//右下
Point getThree(ll x0,ll y0,int n){
ll a=2,b=n-1;
Point point=Point{x0+ksm(a,b),y0};
return point;
}
//左下
Point getFour(ll x0,ll y0,int n){
ll a=2,b=n-1;
Point point=Point{-y0+1+ksm(a,b),x0};
return point;
}
/**
* 给定编号、层数,获取在哪个部分
* @n 层数 (n>=2)
* @index 编号
*/
int getPart(ll n,ll index){
ll div=ksm(4,n-1);
int part=0;
for(int i=1;i<=4;i++){
part++;
index-=div;
if(index<=0)break;
}
return part;
}
void coutPoint(Point p){
}
/**
* @nowN 当前层数
* @index 所求房子编号
* @part 当前层在下一层的位置
*/
Point solve(ll nowN,ll index,ll nextPart,bool isFirst){
//printf("solve(%lld,%lld,%lld)\n",nowN,index,nextPart);
if(nowN==1){
if(index==1){
switch(nextPart){
case 0:
return Point{1,2};
case 1:
return getOne(1,2,nowN+1);
case 2:
return getTwo(1,2,nowN+1);
case 3:
return getThree(1,2,nowN+1);
case 4:
return getFour(1,2,nowN+1);
}
}else if(index==2){
switch(nextPart){
case 0:
return Point{2,2};
case 1:
return getOne(2,2,nowN+1);
case 2:
return getTwo(2,2,nowN+1);
case 3:
return getThree(2,2,nowN+1);
case 4:
return getFour(2,2,nowN+1);
}
}else if(index==3){
switch(nextPart){
case 0:
return Point{2,1};
case 1:
return getOne(2,1,nowN+1);
case 2:
return getTwo(2,1,nowN+1);
case 3:
return getThree(2,1,nowN+1);
case 4:
return getFour(2,1,nowN+1);
}
}else if(index==4){
switch(nextPart){
case 0:
return Point{1,1};
case 1:
return getOne(1,1,nowN+1);
case 2:
return getTwo(1,1,nowN+1);
case 3:
return getThree(1,1,nowN+1);
case 4:
return getFour(1,1,nowN+1);
}
}
}
int nowPart=getPart(nowN,index);//当前部分
ll newIndex=-1;//上一层的index
if(nowPart==2||nowPart==3){
//cout<<"test 1"<<endl;
if((index%ksm(4,nowN-1))==0){
newIndex=ksm(4,nowN-1);
}else{
newIndex=index%ksm(4,nowN-1);
}
}else if(nowPart==1||nowPart==4){
//cout<<"test 2"<<endl;
ll x=index%ksm(4,nowN-1);
if(x==0){
newIndex=1;
}else{
newIndex=ksm(4,nowN-1)+1-x;
}
}
Point point=solve(nowN-1,newIndex,nowPart,0);
//cout<<"return:";
//coutPoint(point);
if(isFirst)return point;
switch(nextPart){
case 1:
return getOne(point.x,point.y,nowN+1);
case 2:
return getTwo(point.x,point.y,nowN+1);
case 3:
return getThree(point.x,point.y,nowN+1);
case 4:
return getFour(point.x,point.y,nowN+1);
}
}
ll absA(ll a){
if(a<0)return -a;
return a;
}
double getDis(Point p1,Point p2){
ll deltaX=absA(p1.x-p2.x);
ll deltaY=absA(p1.y-p2.y);
ll tmp=(deltaX*deltaX)+(deltaY*deltaY);
return sqrt(tmp)*10;
}
int main(){
int t;
cin>>t;
while(t--){
ll floor,index1,index2;
cin>>floor>>index1>>index2;
Point p1=solve(floor,index1,0,1);
Point p2=solve(floor,index2,0,1);
printf("%0.lf\n",getDis(p1,p2));
}
return 0;
}