AcWing - 98 - 分形之城

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

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;

void U(ll, ll, int, ll, ll, ll, ll);
void D(ll, ll, int, ll, ll, ll, ll);
void R(ll, ll, int, ll, ll, ll, ll);

vector<pair<ll, ll> >ans;
//len是完全图里当前区域的边长的1/2
void L(ll x, ll y, int n, ll id, ll idl, ll idr, ll len) {
    if(n == 0) {
        ans.push_back({x, y});
        return;
    }
    ll idlen = (idr - idl) / 4;
    if(id < idl + idlen)
        U(x, y, n - 1, id, idl, idl + idlen, len / 2);
    else if(id < idl + 2 * idlen)
        L(x, y + len, n - 1, id, idl + idlen, idl + 2 * idlen, len / 2);
    else if(id < idl + 3 * idlen)
        L(x + len, y + len, n - 1, id, idl + 2 * idlen, idl + 3 * idlen, len / 2);
    else
        D(x + len, y, n - 1, id, idl + 3 * idlen, idl + 4 * idlen, len / 2);
}

//len是完全图里当前区域的边长的1/2
void U(ll x, ll y, int n, ll id, ll idl, ll idr, ll len) {
    //printf("U[%lld,%lld,%d],[%lld,%lld]\n", x, y, n,idl,idr-1);
    if(n == 0) {
        ans.push_back({x, y});
        return;
    }
    ll idlen = (idr - idl) / 4;
    if(id < idl + idlen)
        L(x, y, n - 1, id, idl, idl + idlen, len / 2);
    else if(id < idl + 2 * idlen)
        U(x + len, y, n - 1, id, idl +  idlen, idl + 2 * idlen, len / 2);
    else if(id < idl + 3 * idlen)
        U(x + len, y + len, n - 1, id, idl + 2 * idlen, idl + 3 * idlen, len / 2);
    else
        R(x, y + len, n - 1, id, idl + 3 * idlen, idl + 4 * idlen, len / 2);
}

//len是完全图里当前区域的边长的1/2
void R(ll x, ll y, int n, ll id, ll idl, ll idr, ll len) {
    //printf("R[%lld,%lld,%d],[%lld,%lld]\n", x, y, n,idl,idr-1);
    if(n == 0) {
        ans.push_back({x, y});
        return;
    }
    ll idlen = (idr - idl) / 4;
    if(id < idl + idlen)
        D(x + len, y + len, n - 1, id, idl, idl + idlen, len / 2);
    else if(id < idl + 2 * idlen)
        R(x + len, y, n - 1, id, idl + idlen, idl + 2 * idlen, len / 2);
    else if(id < idl + 3 * idlen)
        R(x, y, n - 1, id, idl + 2 * idlen, idl + 3 * idlen, len / 2);
    else
        U(x, y + len, n - 1, id, idl + 3 * idlen, idl + 4 * idlen, len / 2);
}

//len是完全图里当前区域的边长的1/2
void D(ll x, ll y, int n, ll id, ll idl, ll idr, ll len) {
    //printf("D[%lld,%lld,%d],[%lld,%lld]\n", x, y, n,idl,idr-1);
    if(n == 0) {
        ans.push_back({x, y});
        return;
    }
    ll idlen = (idr - idl) / 4;
    if(id < idl + idlen)
        R(x + len, y + len, n - 1, id, idl, idl + idlen, len / 2);
    else if(id < idl + 2 * idlen)
        D(x, y + len, n - 1, id, idl + idlen, idl + 2 * idlen, len / 2);
    else if(id < idl + 3 * idlen)
        D(x, y, n - 1, id, idl + 2 * idlen, idl + 3 * idlen, len / 2);
    else
        L(x + len, y, n - 1, id, idl + 3 * idlen, idl + 4 * idlen, len / 2);
}

int main() {
#ifdef Yinku
    freopen("Yinku.in", "r", stdin);
#endif // Yinku
    int T;
    while(~scanf("%d", &T)) {
        while(T--) {
            ll n, x, y;
            scanf("%lld%lld%lld", &n, &x, &y);
            ans.clear();
            //len,每个四分之一块的边长
            L(1, 1, n, x, 1, (1ll << (2ll * n)) + 1ll, 1ll << (n - 1));
            L(1, 1, n, y, 1, (1ll << (2ll * n)) + 1ll, 1ll << (n - 1));
            //printf("[%lld,%lld]\n", ans[0].first, ans[0].second);
            //printf("[%lld,%lld]\n", ans[1].first, ans[1].second);
            double dx = abs(ans[0].first - ans[1].first) * 10.0;
            double dy = abs(ans[0].second - ans[1].second) * 10.0;
            double dis = sqrt(dx * dx + dy * dy);
            printf("%lld\n", (ll)round(dis));
        }
    }
}

转载于:https://www.cnblogs.com/Inko/p/11424782.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值