サマースクールキャンプ(第十フィールド)オフ以上2019頭の牛E-ヒルベルトソート(フラクタル)

>ポータル<

問題の意味


あなたが今与えられている$ N $と$ K $、$を座標のnあなたはヒルベルト曲線$座標-order与えられた$ kが$に応じてアレンジしましょう

ヒルベルト曲線を次のように

      $ k = 1 $ $ K = 2 $ $ K = 3 $
$ 2 ^ {K} $平坦な正方形の一辺の長さは、4つの部分に分けることができる:①②左上、右上底部は③右下を左④

$ K-1 $リリース発注ヒルベルト曲線によって$ K $順ヒルベルト曲線。

 (1)の$ K-1 $ヒルベルト曲線主対角線①部分を反転した順序に従って。

 (2)$のK-1 $順ヒルベルト曲線に②③部分コピー。

 (3)$のK-1の対角部分を反転させたサブ順ヒルベルト曲線④に従って$。

上記のように、それぞれ、一次、二次、三次ヒルベルト曲線

分析


アルゴリズムをソートした後、明確に定義された比較関数を直接呼び出すことができます。

本質的に一次元マッピングの二次元のためのヒルベルト曲線は、私たちは、最初の数回のパスであり、次いでソートプリヒルベルト曲線の各々に対する点を考慮することができます。

図から分かるように、原点を中心に正方形を確立することとし、次に左上、左下、右下、右上、および4つの象限ヒルベルトトレース機能の原点を通る連続ヒルベルト曲線は、互いに対称でありますそれが通過する前に、異なる象限のために、四分円は、最初の2つの点の相対座標は、小さいサイズ続けるに再帰的に、ヒルベルト曲線を異なる対称変換を行い、点の総数を算出します。

座標系の実際のタイトルを確立するようなものである(ここで私はピット、不思議を植えどのようにそれをすべて間違っています)

 

コード(これはそれほど単純ではありませんが、より高い可読性)

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e6+5;
struct node{
    ll x, y, f;
    bool operator<(const node& a)const{
        return f<a.f;
    }
}p[maxn];
 
int f(ll k,ll x,ll y){
    if(k==0) return 1;
    ll n = 1<<(k-1);
    if(x<=n){
        if(y<=n)return f(k-1,y,x);
        y-=n; return f(k-1,n-y+1,n-x+1)+n*n*3;
    }else{x-=n;
        if(y<=n)return f(k-1,x,y)+n*n;
        y-=n;return f(k-1,x,y)+n*n*2;
    }

}

int main()
{
    int n, k;
    scanf("%d%d", &n, &k);
    for(int i = 0; i < n; i++){
        scanf("%lld%lld", &p[i].x, &p[i].y);
        p[i].f = f(k,p[i].x,p[i].y);
    }
    sort(p, p+n);
    for(int i = 0; i < n; i++) printf("%lld %lld\n", p[i].x, p[i].y);
    return 0;
}
View Code

 

おすすめ

転載: www.cnblogs.com/wizarderror/p/11431775.html