网址:https://www.acwing.com/problem/content/100/
题意:
说着太复杂了,直接看原网页吧$QAQ$。
题解:
首先我们先推一下公式,就是这个点,在高一级图中的另外三个子图的对应位置应该怎么表示出来。首先在$n-1$级图中$2^{2n-2}$个房子,我们将其编号成$0$到$2^{2n-2}-1$,然后$n$级图中的$m$号房子$n-1$级图的房子整除就知道了房子在哪个$n-1$级图中。取模则知道了对应于这个$n-1$级图的哪个房子,然后继续递归直到一级图上,回溯时加上这个图上的点对应于$n-1$级图的偏移量,最后计算出欧氏距离即可。
偏移量:设在$n-1$级图的坐标是$(x,y)$,$n-1$级图长度为$len$,则:
如果在$n$级图中的$1$号图,则实际坐标为$(y,x)$。
如果在$n$级图中的$1$号图,则实际坐标为$(x,y+len)$。
如果在$n$级图中的$1$号图,则实际坐标为$(x+len,y+len)$。
如果在$n$级图中的$1$号图,则实际坐标为$(len×2-y-1,len-x-1)$。
AC代码:
#include <bits/stdc++.h> using namespace std; typedef long long ll; pair<ll, ll> calc(int n, ll m) { if (n == 0) return make_pair(0, 0); ll len = 1ll << (n - 1), cnt = 1ll << ((n << 1) - 2); auto p = calc(n - 1, m % cnt); ll x = p.first, y = p.second; ll z = m / cnt; if (z == 0) return make_pair(y, x); else if (z == 1) return make_pair(x, y + len); else if (z == 2) return make_pair(x + len, y + len); else if (z == 3) return make_pair(-y + (len << 1) - 1, -x + len - 1); } double dist(pair<ll, ll>& a, pair<ll, ll>& b) { return sqrt((a.first - b.first) * (a.first - b.first) + (a.second - b.second) * (a.second - b.second)); } int main() { int T; scanf("%d", &T); while (T--) { int n; ll s, d; scanf("%d%lld%lld", &n, &s, &d); auto p1 = calc(n, s - 1), p2 = calc(n, d - 1); double dis = dist(p1, p2); printf("%0.0f ", dis * 10); } return 0; }