AcWing 98. 分形之城—递归、分治

题目链接:AcWing 98. 分形之城
问题描述
在这里插入图片描述
分析
这一道题看起来很麻烦,其实就是比较麻烦。
这是一道递归+坐标变换的问题,坐标变换比较难想,建议自己动手画一画容易明白一些。
首先是城市等级 n n n 与总点数的关系,不难发现总点数 = 2 2 ∗ n =2^{2*n} =22n,同时可以发现,每个等级由 4 4 4个等级为 n − 1 n-1 n1的城市构成,将每个等级为 n − 1 n-1 n1的城市表示为 b l o c k block block 每个 b l o c k block block 的点数为 = 2 2 ∗ ( n − 1 ) = 2 2 ∗ n − 2 =2^{2*(n-1)}=2^{2*n-2} =22(n1)=22n2个,观察可以发现城市由 b l o c k block block 构成的规律,第1部分是关于 y = x 对称 y=x对称 y=x对称 ,第2部分是与 b l o c k block block相同,第3部分是与 b l o c k block block相同,第4部分是关于 y = 2 n − 1 − x 对称 y=2^{n-1}-x对称 y=2n1x对称
分别考虑当前点在城市的 4 4 4个区域的情况递归子问题即可
在这里插入图片描述

代码如下:

#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cmath>
using namespace std;
typedef long long ll;
struct node{
    ll x,y;
};
node get(ll n,ll a){
    if(n==0) return {0,0};
    ll block=1ll<<(2*n-2);
    ll len=1ll<<(n-1);
    node b=get(n-1,a%block);
    ll x=b.x,y=b.y;
    if(a/block==0) return {y,x};
    if(a/block==1) return {x,y+len};
    if(a/block==2) return {x+len,y+len};
    if(a/block==3) return {2*len-1-y,len-1-x};
}
int main(){
    int t;
    cin>>t;
    while(t--){
        ll n,a,b;
        cin>>n>>a>>b;
        node pa=get(n,a-1);
        node pb=get(n,b-1);
        ll dx=pa.x-pb.x;
        ll dy=pa.y-pb.y;
        // cout<<dx<<" "<<dy<<endl;
        printf("%.0lf\n",sqrt(dx*dx+dy*dy)*10);
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

chp的博客

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值