题目大意:
有
组数据,
每组给出3个数
求在分形图中第
级情况下,编号为
和
的两个点之间的距离
为多少。
如图:
分形图随等级增加而增大即每增加一级:
1.右下角,右上角复制一遍
2.顺时针旋转
度,放到左上角
3.逆时针旋转
度,放到左下角
4.各部分首尾相连
编号是从左上角那个点开始计 ,沿着道路依次计数。
分析:
分治,
每次拆成找当前的需要的点
在左上,右上,左下,右上哪个部分然后递归过去,
慢慢拆开然后在过程中计算坐标的位置即可。
不过细节略多。
代码:
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#define N 40
using namespace std;
typedef long long ll;
ll num[N];
void dfs(ll n, ll cnt, ll &x, ll &y)
{
if (n == 1)
{
if (cnt == 1) x = 1, y = 1;
if (cnt == 2) x = 1, y = 2;
if (cnt == 3) x = 2, y = 2;
if (cnt == 4) x = 2, y = 1;
return;
}
ll tot = num[n] * num[n] / 4;
if (cnt <= tot)
{
dfs(n - 1, cnt, y, x);
return;
}
if (cnt <= 2*tot)
{
dfs(n - 1, cnt - tot, x, y);
y += num[n] >> 1;
return;
}
if (cnt <= 3*tot)
{
dfs(n - 1, cnt - 2*tot, x, y);
x += num[n]>>1;
y += num[n]>>1;
return;
}
dfs(n - 1, cnt - 3*tot, y, x);
x = num[n] - x + 1;
y = (num[n]>>1) - y + 1;
}
int main()
{
num[0] = 1;
for (int i = 1; i <= 31; i++) num[i] = num[i-1]<<1;
int T, n;
ll A, B;
scanf("%d", &T);
while (T--)
{
scanf("%d %lld %lld", &n, &A, &B);
ll x1, x2, y1, y2;
dfs(n, A, x1, y1);
dfs(n, B, x2, y2);
ll ans = sqrt((x1 - x2)*(x1 - x2) + (y1 - y2)*(y1 - y2)) * 10 + 0.5;
printf("%lld\n", ans);
}
return 0;