【算法】HZOJ-239不规则的街道


[不规则的街道 - 题目 - Online Judge] https://oj.haizeix.com/problem/239

题目描述

城市扩建的规划是个令人头疼的大问题。规划师设计了一个极其复杂的方案:当城市规模扩大之后,把与原来城市结构一样的区域复制或旋转 90 度之后建设在原来的城市周围(详细地说,将原来的城市复制一遍放在原城市上方,将顺时针旋转 90 度后的城市放在原城市的左上方,将逆时针旋转 90 度后的城市放在原城市的左方),再用道路将四部分首尾连接起来,如下图所示。

在这里插入图片描述

容易看出,扩建后的城市的各个房屋仍然由一条道路连接。定义 N 级城市为拥有 22N 座房屋的城市。对于任意等级的城市,从左上角开始沿着唯一的道路走,依次为房屋标号,就能够得到每间房及的编号了。住在其中两间房屋里的人们想知道,如果城市发展到了一定等级,他俩各自所处的房屋之间的直线距离是多少。你可以认为图中的每个格子都是边长为 10 米的正方形,房屋均位于每个格子的中心点上( T 次询问,每次输入等级 N ,两个编号 SD ,求 SD 之间的直线距离。


输入

第一行输入一个整数 T

接下来 T 行,每行输入三个整数 N,S,D。(1≤T≤104,1≤N≤31)

输出

对于每次询问输出一行一个整数,表示两点间的直线距离。输出四舍五入到整数。


Code

#include <bits/stdc++.h>
#define endl '\n'

using namespace std;

#define S(a) ((a) * (a))

void f(long long n, long long s, long long &x, long long &y){
	if (n == 1){
		if (s == 1) x = 0, y = 0;
		else if (s == 2) x = 0, y = 1;
		else if (s == 3) x = 1, y = 1;
		else x = 1, y = 0;
		return ;
	}
	long long L = 1LL << (n - 1);
	long long block = L * L;
	long long xx, yy;
	if (s <= block) { // 1: (x, y) -> (y, x)
		f(n - 1, s, xx, yy);
		x = yy, y = xx;
	} else if (s <= 2 * block){ // 2:(x, y) -> (x,y + L);
		f(n - 1, s - block, xx, yy);
		x = xx, y = yy + L;
	} else if (s <= 3 * block){ // 3:(x, y) -> (x + L, y + L)
		f(n - 1, s - 2 * block, xx, yy);
		x = xx + L, y = yy + L;
	} else { // 4:(x, y) -> (2 * L - y - 1, L - x - 1)
		f(n - 1, s - 3 * block, xx, yy);
		x = 2 * L - yy - 1, y = L - xx - 1;
	}
	return ;
}

int main(){
	cin.tie(0), cout.tie(0);
	long long t, n, s, d;
	scanf("%lld", &t);
	while (t --){
		scanf("%lld%lld%lld", &n, &s, &d);
		long long sx, sy, dx, dy;
		f(n, s, sx, sy);
		f(n, d, dx, dy);
		printf("%.0lf\n", 10 * sqrt(S(sx - dx) + S(sy - dy)));
	}
	return 0;
}

解题思路

分型

分型,是指整体图形可以分成若干个部分,每一部分都是整体缩小后的形状。

题目分析

本题是一道典型的分形系统,一个图片,可以分成如下四个区域。

在这里插入图片描述

①.所有编号减0,等价于原图顺时针旋转90度,在做轴对称,所有坐标加(0,0)
②.所有编号减4,等价于原图,所有坐标加(0,n)
③.所有编号减8,等价于原图,所有坐标加(n,n)
④.所有编号减12,等价于原图逆时针旋转90度,再做轴对称,所有坐标加(n,0)

坐标变换

在这里插入图片描述

N*M的矩阵,坐标为(x,y),坐标从0开始,经过如下操作:

顺时针旋转90度:(x,y)→(y,N-x-1)

逆时针旋转90度:(x,y)→(M-y-1,x)

​ 轴对称:(x,y)→(x,M-y-1)

最终分析

假设,现在已计算得到对应区域点在原图中的坐标为(x,y)

当前城市等级为n,原图等级为n-1,边长为 L = 2 n − 1 L=2^{n-1} L=2n1

在这里插入图片描述

①.(x,y)→(y,L-x-1)→(y,x)
②.(x,y)→(x,y+L)
③.(x,y)→(x+L,y+L)
④.(x,y)→(L-y-1,x)→(L-y-1,L-x-1)→(2L-y-1,L-x-1)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值