题意:传送门
题解:可以知道第
n
n
n等级由第
n
−
1
n-1
n−1等级组成而来的,首先左上角那一部分是由
n
−
1
n-1
n−1等级先绕左上角逆时针转
27
0
o
270^o
270o,然后与
x
x
x轴对称得到,第
n
n
n等级的右上角那块直接由第
n
n
n等级平移过来,第
n
n
n等级的右下角也是平移相对应的位置得到,第
n
n
n等级的左下角部分是最复杂的部分,由第
n
n
n等级的部分先绕左上角逆时针旋转
9
0
o
90^o
90o然后与
x
x
x轴对称得到,然后再平移相应的位置得到,这里的平移相应的位置都可以进行手算推导出来,重点在于点逆时针旋转
θ
\theta
θ度后坐标的变换,公式为:
(
x
,
y
)
∗
[
c
o
s
θ
s
i
n
θ
−
s
i
n
θ
c
o
s
θ
]
=
[
x
∗
c
o
s
θ
−
y
∗
s
i
n
θ
x
∗
s
i
n
θ
+
y
∗
c
o
s
θ
]
\left ( x,y \right )*\begin{bmatrix} cos\theta & sin\theta\\ -sin\theta & cos\theta \end{bmatrix}=\begin{bmatrix} x*cos\theta-y*sin\theta\\ x*sin\theta+y*cos\theta \end{bmatrix}
(x,y)∗[cosθ−sinθsinθcosθ]=[x∗cosθ−y∗sinθx∗sinθ+y∗cosθ]证明自己可以画图然后自证即可。属于递归中的困难题目了。
附上代码:
#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
typedef long long ll;
typedef pair<ll,ll>Pll;
int T;
ll n,a,b;
Pll calc(ll n,ll m)
{
if(n==0)return {0,0};
ll len=1ll<<(n-1),cnt=1ll<<(2*n-2);
auto pos=calc(n-1,m%cnt);
auto x=pos.first,y=pos.second;
auto z=m/cnt;
if(z==0)return {y,x};
if(z==1)return {x,y+len};
if(z==2)return {x+len,y+len};
return {2*len-1-y,len-1-x};
}
int main()
{
cin>>T;
while(T--){
cin>>n>>a>>b;
auto ac=calc(n,a-1);
auto bc=calc(n,b-1);
double x=ac.first-bc.first,y=ac.second-bc.second;
printf("%.0f\n",sqrt(x*x+y*y)*10);
}
return 0;
}