Fractal Streets poj3889

城市的规划在城市建设中是个大问题。

不幸的是,很多城市在开始建设的时候并没有很好的规划,城市规模扩大之后规划不合理的问题就开始显现。

而这座名为 Fractal 的城市设想了这样的一个规划方案,如下图所示:

Fractal Streets poj3889

当城区规模扩大之后,Fractal 的解决方案是把和原来城区结构一样的区域按照图中的方式建设在城市周围,提升城市的等级。

对于任意等级的城市,我们把正方形街区从左上角开始按照道路标号。

虽然这个方案很烂,Fractal 规划部门的人员还是想知道,如果城市发展到了等级 N,编号为 A 和 B 的两个街区的直线距离是多少。

街区的距离指的是街区的中心点之间的距离,每个街区都是边长为 10 米的正方形。

输入格式

第一行输入正整数n,表示测试数据的数目。

以下n行,输入n组测试数据,每组一行。

每组数据包括三个整数 N,A,B, 表示城市等级以及两个街区的编号,整数之间用空格隔开。

输出格式

一共输出n行数据,每行对应一组测试数据的输出结果,结果四舍五入到整数。

数据范围

1≤n≤1000

输入样例:

3 
1 1 2 
2 16 1 
3 4 33 

输出样例:

10 
30 
50 

基本图形,标号为     ⭐注意:图中虽然标号在格子内,其实指的是格子左上角的点(是一个坐标点)

Fractal Streets poj3889                  

图4

图4中方向变成左上角的方向,只需将x,y坐标互换,即在图4(x,y)变为(y, x)

Fractal Streets poj3889

 图5

变成右上角 ,只要图4(x,y)变为(x,y + len)len(为这一层城市边长的一半)

Fractal Streets poj3889

 图6

右下角,图4(x,y)变为(x + len, y + len)

Fractal Streets poj3889

 图7

左下角,最难的,好几部变换 (x,y) -》 (x ,y - (len - 1))-》 (-(y - len + 1),-x)即(len - y - 1,-x)-》(len - y + len,(len - 1) - x)

Fractal Streets poj3889       Fractal Streets poj3889    Fractal Streets poj3889

 特别注意 先左移让 y - len, 但是!!!!我们要让最右上角的坐标是原点,所以 是 y -len + 1, 那为什么不是 y - len + (len/2)呢?

 因为我们虽然分成了左上、右上、左下、右下,其实每个小个子中可能还可以再分成4块,我们的目的是为了让最 右上角的坐标为原点(其他的所有小房子围着它坐标变换)所以在平移一个单位距离1,而不是(len/2)这样相当于对于右上变换(而右上中的坐标也是要变换的所以,不能是len/2)

⭐注意:图中虽然标号在格子内,其实指的是格子左上角的点(是一个坐标点)

#include <bits/stdc++.h>
#define ll long long
#define P pair<ll,ll>
using namespace std;

int t,n;

P calc(int n, ll m)
{
    if (!n) return {0, 0};
    ll len = 1ll << (n - 1), cnt = 1ll << ((n << 1) - 2);
    P a = calc(n - 1, m % cnt);
    ll x = a.first, y = a.second;
    int z = m / cnt;
    if (!z) return {y, x};
    if (z == 1) return {x, y + len};
    if (z == 2) return {x + len, y + len};
    return {(len << 1) - 1 - y, len - 1 - x};
}

int main()
{
    scanf("%d", &t);
    while (t --)
    {
        ll a, b;
        scanf("%d%lld%lld", &n, &a, &b);
        P x = calc(n, a - 1);
        P y = calc(n, b - 1);
        ll dx = x.first - y.first, dy = x.second - y.second;
        double ans = (sqrt(dx * dx + dy * dy) * 10);
        printf("%0.lf
", ans);
        
    }
}