zoukankan      html  css  js  c++  java
  • 牛客多校第十场 E Hilbert Sort 递归,排序

    题意:

    给你一个方阵,再在方阵上给定一些点,按照希尔伯特曲线经过的先后顺序为这些点排序

    题解:

    定义好比较函数后直接调用排序算法即可。

    希尔伯特曲线本来就是用于二维到一维的映射的,因此我们可以考虑对于每一个点预处理出它是希尔伯特曲线上第几个经过的,然后排序。

    可以看出,假设在方阵的中心设立一个原点,那么希尔伯特曲线依次经过原点的左上,左下,右下,右上,而这四个象限希尔伯特函数的轨迹是互相对称的,对于不同的象限,首先算出它前面经过的象限的总点数,然后将两个点的相对坐标做不同的对称变换后,递归到小一号的希尔伯特曲线中继续。

    #include<iostream>
    #include<algorithm>
    #include<cassert>
    #define LL long long  
    using namespace std;
    inline int pos(const int &x,const int &y){
        if(x==0 && y==0)return 0;
        if(x==1 && y==0)return 1;
        if(x==1 && y==1)return 2;
        if(x==0 && y==1)return 3;
    }
    struct Hbt{
        LL x,y;
        int size;
        LL rank;
        LL calc_rank(){
            rank=0;
            LL xx=x,yy=y;
            LL w=1<<(size-1);
            while(w){
                int _pos=pos((int)xx/w,(int)yy/w);
                rank+=w*w*_pos;
                if(_pos==1 || _pos==2){
                    //保持原状 
                    xx%=w;
                    yy%=w;
                }else if(_pos==0){
                    //左下右上互换 
                    xx%=w;
                    yy%=w;
                    swap(xx,yy);
                }else if(_pos==3){
                    //左上右下互换 
                    xx=w-1-xx%w;
                    yy=w-1-yy%w;
                    swap(xx,yy);
                }
                w>>=1;
            }
            rank+=pos((int)xx,(int)yy);
            return rank;
        }
        friend bool operator <(const Hbt &a,const Hbt &b){
            return a.rank<b.rank;
        }
        Hbt(){}
        Hbt(LL a,LL b,int c){
            x=a;y=b;size=c;
        } 
    }p[1000006];
    int main(){
        //为计算方便坐标减一存储 
        int n,k;
        scanf("%d %d",&n,&k);
        for(int i=1;i<=n;i++){
            scanf("%lld %lld",&p[i].x,&p[i].y);
            --p[i].x;--p[i].y;
            p[i].size=k;
            p[i].calc_rank();
        }
        sort(p+1,p+1+n);
        for(int i=1;i<=n;i++){
            printf("%lld %lld
    ",p[i].x+1,p[i].y+1);
        }
        return 0;
    }
  • 相关阅读:
    谈Delphi编程中“流”的应用 (一)
    Ihtmldocument2接口的使用
    TWebBrowser 异常 invalid floating point operation
    万一的 Delphi 博客 (注意 delphi的新功能)
    正则表达式应用(一)
    查询数据库所有表所有字段的某个值,生成更新代码 (VB)
    正则表达式应用(二)
    让程序支持脚本
    查探对方是否加你为好友
    常用的一些批处理,脚本功能(一)
  • 原文地址:https://www.cnblogs.com/isakovsky/p/11372312.html
Copyright © 2011-2022 走看看