Input
On the first line of the input is a positive integer, the number of test cases. Then for each test case:
A line containing a three positive integers, n < 16 and h, o < 231, specifying the order of the Hilbert curve, and the house numbers of the offered house and the local city planning office.
Output
For each test case:
One line containing the distance Chris will have to fly to his work in meters, rounded to the nearest integer.
Sample Input
3
1 1 2
2 16 1
3 4 33
Sample Output
10
30
50
递归
求st;ed
号房屋在N
级城市中的位置,求他们之间的直线距离
思路:
从N-1
级城市入手,可以通过变换得到在N
级城市中的位置
具体思路不写了,书上很清楚,感觉旋转、水平翻转坐标那里不好想
想成一个正方形在滚动,坐标中的xy
是长度,翻滚的时候长度不变,然后就可以根据边长推出新坐标了
非常要吐槽,也是平时注意不到的一个地方就是在求sqrt
之类的东西是变量的类型,因为poj
不支持c++11
每次在提交的时候都要改一些东西TAT
#include <cmath>
#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;
/* static const auto io_sync_off = []() {
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
return nullptr;
}(); */
using ll = long long;//提交需要改成typedef
using paii = pair<ll, ll>;
paii calc(int n, ll m)
{
if (n == 0)
return make_pair(0, 0);
ll len = 1 << n - 1, cnt = 1 << 2 * n - 2;//n-1级城市边长,房屋数量
paii pos = calc(n - 1, m % cnt);//n-1级城市中的编号为m%cnt
ll x = pos.first, y = pos.second;
ll num = m / cnt;//在n-1级城市中哪个城市
if (num == 0)//左上
return make_pair(y, x);
if (num == 1)//右上
return make_pair(x, y + len);
if (num == 2)//右下
return make_pair(x + len, y + len);
if (num == 3)//左下
return make_pair(2 * len - y - 1, len - x - 1);
}
int main()
{
int T;
cin >> T;
while (T--)
{
int n, st, en;
cin >> n >> st >> en;
st -= 1, en -= 1;
paii stNum = calc(n, st);
paii enNum = calc(n, en);
/* cout<<stNum.first<<" "<<stNum.second<<endl;
cout<<enNum.first<<" "<<enNum.second<<endl; */
double dx = double(stNum.first - enNum.first);//必须保持类型一致
double dy = double(stNum.second - enNum.second);
printf("%.0f\n", (double)sqrt(dx * dx + dy * dy) * 10);
}
return 0;
}