AcWing 98. 分形之城 题解
Tag:递归
题面
【题目描述】
城市的规划在城市建设中是个大问题。
不幸的是,很多城市在开始建设的时候并没有很好的规划,城市规模扩大之后规划不合理的问题就开始显现。
而这座名为 Fractal 的城市设想了这样的一个规划方案,如下图所示:
当城区规模扩大之后,Fractal 的解决方案是把和原来城区结构一样的区域按照图中的方式建设在城市周围,提升城市的等级。
对于任意等级的城市,我们把正方形街区从左上角开始按照道路标号。
虽然这个方案很烂,Fractal 规划部门的人员还是想知道,如果城市发展到了等级
街区的距离指的是街区的中心点之间的距离,每个街区都是边长为
【数据范围】
思路
首先这道题一眼递归,通过
那我们不妨在图形中央建系。
那我们接下来考虑的就是坐标信息如何转移了。
1.坐标信息的转移
首先我们需要一些数学芝士铺垫一下:
- 对于点
,沿原点顺时针旋转 ,将变为 。 - 对于点
,沿原点逆时针旋转 ,将变为 。 - 对于点
,以 轴为对称轴翻转将变为 。
我们直接探究等级
仔细观察左上角是由等级
右上角和右下角都是直接平移,不需要改变。
左下角是由等级
然后就根据象限平移就行了(具体细节见代码)。
2.计算距离
最后计算距离只需要
因为原点是在图形中央的,而距离计算的是每个村庄中心点间的距离。
举个栗子:
若计算
最后 一定要开
#include<bits/stdc++.h>
#define int long long
#define PII pair<int,int>
using namespace std;
int q,n,a,b;
PII solve(int n,int m)//细节m是从0开始的
{
if(n==0) return {0,0};
int len=1LL<<(n-1);//象限边长 2^{n-1} 不写1LL两行泪
int cnt=1LL<<(2*n-2);//象限总数 4^{n-1}
PII xx=solve(n-1,m%cnt);//上一等级的坐标信息
int x=xx.first,y=xx.second;
int z=m/cnt;//判断处于哪个象限
/*
象限分布为(由等级 1 定义而来)
0|1
———
3|2
0为第二象限,1为第一象限,2为第四象限,3为第三象限
*/
if(z==0)
{
//(x,y)顺转90->(y,-x)翻转y轴->(-y,-x)平移->(-y-len,-x+len)
return {-y-len,-x+len};
}
else if(z==1)
{
//(x,y)平移->(x+len,y+len)
return {x+len,y+len};
}
else if(z==2)
{
//(x,y)平移->(x+len,y-len)
return {x+len,y-len};
}
else
{
//(x,y)逆转90->(-y,x)翻转y轴->(y,x)平移->(y-len,x-len)
return {y-len,x-len};
}
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin>>q;
while(q--)
{
cin>>n>>a>>b;
PII x=solve(n,a-1);//细节从0开始
PII y=solve(n,b-1);
double w=(double)x.first-y.first,v=(double)x.second-y.second;
double ans=sqrt(w*w+v*v)*5;//距离公式 细节原点是在图形中央,所以距离只用乘5
cout<<fixed<<setprecision(0)<<ans<<"\n";//四舍五入
}
return 0;
}
本文作者:yaaaaaan
本文链接:https://www.cnblogs.com/yaaaaaan/p/18675265
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步