返回顶部

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));
        }
    }
}
posted @ 2019-08-28 16:22  Inko  阅读(146)  评论(0编辑  收藏  举报