• 牛客多校第十场 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;
    }
  • 相关阅读:
    UIScrollView的滚屏
    ASIHTTPRequest 详解, 够详细
    Libxml2中使用xpath解析xml问题
    new Random()结果相同问题
    UINavigationController使用的一些技巧
    Objectivec 模拟http请求
    开发视频网站,asp.net视频文件转换.flv格式(转)
    jqueryjCarousel 配置选项
    NSDate和NSString之间的转换,(可以转时区的哈)
    NSLog的格式
  • 原文地址:https://www.cnblogs.com/isakovsky/p/11372312.html
Copyright © 2020-2023  润新知