ACwing98 分形之城 分形图

网址:https://www.acwing.com/problem/content/100/

题意:

说着太复杂了,直接看原网页吧$QAQ$。

题解:

首先我们先推一下公式,就是这个点,在高一级图中的另外三个子图的对应位置应该怎么表示出来。首先在$n-1$级图中$2^{2n-2}$个房子,我们将其编号成$0$到$2^{2n-2}-1$,然后$n$级图中的$m$号房子$n-1$级图的房子整除就知道了房子在哪个$n-1$级图中。取模则知道了对应于这个$n-1$级图的哪个房子,然后继续递归直到一级图上,回溯时加上这个图上的点对应于$n-1$级图的偏移量,最后计算出欧氏距离即可。

偏移量:设在$n-1$级图的坐标是$(x,y)$,$n-1$级图长度为$len$,则:

如果在$n$级图中的$1$号图,则实际坐标为$(y,x)$。

如果在$n$级图中的$1$号图,则实际坐标为$(x,y+len)$。

如果在$n$级图中的$1$号图,则实际坐标为$(x+len,y+len)$。

如果在$n$级图中的$1$号图,则实际坐标为$(len×2-y-1,len-x-1)$。

AC代码:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
pair<ll, ll> calc(int n, ll m)
{
	if (n == 0)
		return make_pair(0, 0);
	ll len = 1ll << (n - 1), cnt = 1ll << ((n << 1) - 2);
	auto p = calc(n - 1, m % cnt);
	ll x = p.first, y = p.second;
	ll z = m / cnt;
	if (z == 0)
		return make_pair(y, x);
	else if (z == 1)
		return make_pair(x, y + len);
	else if (z == 2)
		return make_pair(x + len, y + len);
	else if (z == 3)
		return make_pair(-y + (len << 1) - 1, -x + len - 1);
}
double dist(pair<ll, ll>& a, pair<ll, ll>& b)
{
	return sqrt((a.first - b.first) * (a.first - b.first) + (a.second - b.second) * (a.second - b.second));
}
int main()
{
	int T;
	scanf("%d", &T);
	while (T--)
	{
		int n;
		ll s, d;
		scanf("%d%lld%lld", &n, &s, &d);
		auto p1 = calc(n, s - 1), p2 = calc(n, d - 1);
		double dis = dist(p1, p2);
		printf("%0.0f\n", dis * 10);
	}
	return 0;
}

 

ACwing98 分形之城 分形图

上一篇:AcWing 3. 完全背包问题


下一篇:AcWing 9. 分组背包问题