题目见:http://noi.openjudge.cn/ch0204/8463/
解题思路:利用左上、右上、左下、右下和上一等级横、纵坐标之间的关系,比如左上的横坐标等于上一等级的纵坐标,左上的纵坐标等于上一等级的横坐标,建立递推关系。
注意点:
1、数据较大,采用long long数据单元
2、结果需要四舍五入,调用round函数
代码如下:
#include <iostream>
#include <iomanip>
#include <math.h>
using namespace std;
long long map[2][5] = { -1, 0, 0, 1, 1, -1, 0, 1,1,0 };
long long decide(int l, long long m) {
long long area = pow(2, 2 * l)/4;
long long temp = (m - 1) / area;
return temp + 1;
}
long long count_y(int l, long long m);
long long count_x(int l, long long m) {
if (l == 1) {
return map[0][m];
}
long long temp = decide(l, m);
long long sum = pow(2, 2 * l);
long long a = pow(2, l-1);
if (temp == 1) {
return count_y(l - 1, m);
}
if (temp == 2)
return count_x(l - 1, m - sum / 4);
if (temp == 3) {
return a + count_x(l - 1, m-sum/4 * 2);
}
return a + a - 1 - count_y(l - 1, sum + 1 - m);
}
long long count_y(int l, long long m) {
if (l == 1) {
return map[1][m];
}
int temp = decide(l, m);
long long sum = pow(2, 2 * l);
long long a = pow(2, l - 1);
if (temp == 1) {
return count_x(l - 1, m);
}
if (temp == 2)
return a + count_y(l - 1, m - sum / 4);
if (temp == 3) {
return a + count_y(l - 1, m - sum / 4 * 2);
}
//cout << " jjujj" << count_x(l - 1, sum + 1 - m) << endl;
return count_x(l - 1, sum + 1 - m);
}
int main() {
int num;
int level;
long long m, n;
cin >> num;
while (num--) {
cin >> level >> m >> n;
long long m_x = count_x(level, m);
long long m_y = count_y(level, m);
long long n_x = count_x(level, n);
long long n_y = count_y(level, n);
//cout << m_x << " " << m_y << " " << n_x << " " << n_y << endl;
long long dis = round(sqrt(pow((m_x - n_x) * 10, 2) + pow((m_y - n_y) * 10, 2)));
cout << dis << endl;
}
//system("pause");
return 0;
}