标签:一点 相减 三角形 数学 直线 菱形 相交 相等 正弦
题目来源:算法竞赛进阶指南
题目标签:分治,坐标变换
题目链接:https://www.acwing.com/problem/content/100/
思路:不断递归找到当前点是由上一层中哪个点变换而来,从第一层开始不断向上回溯,通过坐标的变换来找到当前层中的坐标。
#include <iostream>
#include <cmath>
using namespace std;
typedef long long LL;
typedef pair<LL, LL> PLL;
PLL calc(LL n, LL m)
{
if(n == 0) return {0, 0};
//cnt表示n - 1层中一共有多少个节点
//len表示当前n层的地图的一半的宽度
LL len = 1ll << n - 1, cnt = 1ll << 2 * n - 2;
//m % cnt 是当前点在上一层中这个点的序号
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()
{
int T;
cin >> T;
while(T--)
{
LL n, a, b;
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("%.0lf\n", sqrt(x * x + y * y) * 10);
}
return 0;
}
标签:一点 相减 三角形 数学 直线 菱形 相交 相等 正弦
原文地址:https://www.cnblogs.com/wanghai0666/p/13462324.html