递推与递归5 分形之城

博客介绍了如何通过递归方法计算城市街区的坐标,当城市等级变化时,各个区域的等级也随之改变。给定街区编号,可以确定其在子城市中的位置,并进行坐标变换。最终,利用坐标公式计算两个街区之间的距离。代码实现中,定义了一个名为f的递归函数来获取街区坐标,并在solve函数中计算并输出街区间的距离。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在这里插入图片描述
观察图像,如果城市从等级i变为等级i+1,则等级i的左上、右上、右下、左下四个区域从等级i-1变为等级i,同时,观察这四个区域,我们可以知道右上和右下两个区域和一阶的方向是一致的,左上的方向是一阶的方向顺时针转90°,左下的方向是一阶的方向逆时针转90°。
现在考虑如何解决本题。我们要求两个街区的距离,我们可以求出这两个街区的坐标,然后用距离公式求得。所以现在的问题转变为由街区编号k求坐标。对于第i-1阶的城市,其边长len为2i-1,街区个数为cnt=len*len。所以对于第i阶,k%cnt就是该街区所在子城市的编号,k/cnt就是该子城市的位置。所以我们递归求解子城市,再根据子城市的位置不同对坐标做变换。
具体如下:

PII f(ll n,ll x){
    if(n==0)return {0,0};
    ll len=1<<n-1,cnt=len*len;
    PII tmp=f(n-1,x%cnt);
    ll u=x/cnt;
    int xx=tmp.first,yy=tmp.second;
    if(u==0)return {yy,xx};
    if(u==1)return {xx,yy+len};
    if(u==2)return {xx+len,yy+len};
    return {2*len-1-yy,len-1-xx};
}

完整代码:

#include<bits/stdc++.h>
#define ll long long
using namespace std;
typedef pair<ll,ll> PII;
PII f(ll n,ll x){
    if(n==0)return {0,0};
    ll len=1<<n-1,cnt=len*len;
    PII tmp=f(n-1,x%cnt);
    ll u=x/cnt;
    int xx=tmp.first,yy=tmp.second;
    if(u==0)return {yy,xx};
    if(u==1)return {xx,yy+len};
    if(u==2)return {xx+len,yy+len};
    return {2*len-1-yy,len-1-xx};
}
void solve(){
    ll n,a,b;
    cin>>n>>a>>b;
    a--,b--;
    PII p1=f(n,a),p2=f(n,b);
    ll x1=p1.first,y1=p1.second,x2=p2.first,y2=p2.second;
    printf("%.lf\n",(10*sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2))));
}
int main(){
    int T;
    cin>>T;
    while(T--)solve();
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值