「2019牛客多校第十场E」Hilbert Sort【思维】

在这里插入图片描述

题意

  • 就是上面那个图,边长 2 k × 2 k 2^k\times 2^k 2k×2k的矩形是由边长为 2 k − 1 × 2 k − 1 2^{k-1}\times 2^{k-1} 2k1×2k1旋转阔者平移然后拼接而来,每个图从左上角进入,右上角出去,从入口进去一次访问给定的一些节点,问访问顺序

题解

  • 之所以给这题的 t a g tag tag是思维因为如果直接蛮写【记录入口出口分8种情况玩大模拟,队友就是这么干的】也是可以过的,但是可以简便一点做,赛后简单推了一下,首先显然可以求出每个点的时间戳,排序输出就行了,求时间戳的时候,讨论 [ x , y ] [x,y] [x,y]在当前正方形的哪一块【分四块】然后这一小块其实与前一大块是相同大小的【前一大块就是指当前这一大块的直接来源】,然后考虑怎么把这个坐标映射到前一大块,然后就能求解更小的问题了,显然做个对称点就行了
  • 需要一点简单的高中知识:点 [ x 0 , y 0 ] [x_0,y_0] [x0,y0],关于 y = − x + b y=-x+b y=x+b的对称点为 [ b − y 0 , b − x 0 ] [b-y_0,b-x_0] [by0,bx0],关于 y = x + b y=x+b y=x+b的对称点为 [ y 0 − b , x 0 + b ] [y_0-b,x_0+b] [y0b,x0+b]

代码

#include<bits/stdc++.h>

using namespace std;

struct node{
    int x,y;long long step;
    friend bool operator<(const node&a,const node&b) {
        return a.step<b.step;
    }
}a[1000005];
int n,k;

long long dfs(int x,int y,int k)
{
    if(k==0) return 1;
    int siz=(1<<(k-1));
    if(x<=siz) {
        if(y<=siz) return dfs(y,x,k-1);
        return 3LL*siz*siz+dfs(2*siz+1-y,siz+1-x,k-1);
    }else{
        if(y<=siz) return 1LL*siz*siz+dfs(x-siz,y,k-1);
        return 2LL*siz*siz+dfs(x-siz,y-siz,k-1);
    }
}

int main()
{
    scanf("%d %d",&n,&k);
    for(int i=1;i<=n;i++) {
        scanf("%d %d",&a[i].x,&a[i].y);
        a[i].step=dfs(a[i].x,a[i].y,k);
    }
    sort(a+1,a+n+1);
    for(int i=1;i<=n;i++) printf("%d %d\n",a[i].x,a[i].y);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值