大体题意:

告诉你一条希尔伯特曲线的大小,然后给你n 个人,及n 个人的坐标,你的起点是左下角,终点是右下角,按照希尔伯特的曲线去走,按照这个顺序给n个人排序,按顺序输出每个人的名字!

思路:

题目中说到了希尔伯特曲线的画法,其实看图中的规律也能看出来,就是一个四分的过程!

首先希尔伯特曲线大体的趋向是左下方 左上方 右上方 右下方区域!

只不过第一区域顺时针反转了90°,第四区域逆时针反转了90°,2,3区域不变,依次连接整个区域即可!

所以思路也就有了! 我们可以给每个人一个id,id是每个人所在区域的总和!可以分第一区域为a,第二区域为b,,,,

最后按照这个id排序即可!

剩下就是递归的过程! 分情况讨论四个区域!

要注意第一区域和第四区域的旋转!

详细见代码:


#include<cstdio>
#include<cstring>
#include<algorithm>
#include<string>
#include<iostream>
using namespace std;
const int maxn = 200000 + 7;
struct Node{
    char name[50];
    string id;
    bool operator < (const Node& rhs) const {
        return id < rhs.id;
    }
}p[maxn];
string dfs(double x, double y, double s,int level){
    string ans = "";
    double s2 = s/2.0;
    if (level > 0){
        if (x <= s2 && y <= s2){ ans = "a" + dfs(y,x,s2,level-1); }
        else if (x <= s2 && y > s2) { ans = "b" + dfs(x,y-s2,s2,level-1); }
        else if (x > s2 && y > s2) { ans = "c" + dfs(x-s2,y-s2,s2,level-1); }
        else if (x > s2 && y <= s2) { ans = "d" + dfs(s2-y,s-x,s2,level-1); }
    }
    return ans;
}
int main(){
    int n;
    double s;
    while(scanf("%d%lf",&n,&s) == 2){
        for (int i = 0; i < n; ++i){
            int x,y;
            scanf("%d%d%s",&x,&y,p[i].name);
            p[i].id = dfs(x,y,s,30);
        }
        sort(p,p+n);
        for (int i = 0; i < n; ++i)printf("%s\n",p[i].name);
    }
    return 0;
}