参考博客

#include<cstdio>
#include<math.h>
#include<utility>//pair
using namespace std;
#define ll long long
#define pr pair<ll,ll>
#define mp make_pair
pr get(int n,ll m) {//返回值是第n层第m个的坐标
    if (!n) return mp(0,0);
    ll len=1ll<<(n-1),cnt=(1ll<<(2*n))/4;
    pr pos=get(n-1,m%cnt);
//我们把它在下一层的坐标求出来,然后根据它在这一层的方位(左上,左下,右上,右下),还原它旋转移动前的坐标
    ll x=pos.first,y=pos.second,z=m/cnt;
    if (z==0) return mp(y,x);
    else if (z==1) return mp(x,y+len);
    else if (z==2) return mp(x+len,y+len);
    else if (z==3) return mp(-y+2*len-1,-x+len-1);
//z==1,2都是可以直接平移得到,而z==0,3需要旋转
//其实路径的形状并不重要,关键是第n层与第n+1层间的的坐标是怎样变换的。
}
int main() {
    int T,n;
    ll a,b,x,y;
    scanf("%d",&T);
    while(T--) {
        scanf("%d%lld%lld",&n,&a,&b);
        pr A=get(n,a-1),B=get(n,b-1);
        x=A.first-B.first,y=A.second-B.second;
        printf ("%.0lf\n",sqrt(x*x+y*y)*10);
    }
}

这种基础题说它简单吧,它的确不难,主要就是思维难度。但如果基础不扎实的话,这种题目就会让你在考场上耗费很多时间(譬如小蒟蒻我qwq)