2019牛客暑期多校训练营(第十场场)Hilbert Sort(递归
原创
©著作权归作者所有:来自51CTO博客作者nuoyanli的原创作品,请联系作者获取转载授权,否则将追究法律责任
题目来源:
https://ac.nowcoder.com/acm/contest/890/E
题意:
根据递归定义的希尔伯特曲线,给定n个该曲线上的坐标,按顺序输出
思路:
对每个点递归计算它的权值。根据当前层的坐标是x,y,讨论出上层的坐标,递归计算即可
代码:
#include<bits/stdc++.h>
using namespace std;
#define
#define
const int N=1e6+5;
int n,k;
struct node {
int x, y;
ll value;
bool operator<(const node &b) const {
return value < b.value;
}
}p[N];
ll dfs(int x,int y,int k) {
if (k == 0)
return 0;
ll kk = (1ll << k);
ll value = kk * kk;
if (x <= kk / 2 && y <= kk / 2)
return dfs(y, x, k - 1);
else if (x > kk / 2 && y <= kk / 2)
return dfs(x - kk / 2, y, k - 1) + value;
else if (x > kk / 2 && y > kk / 2)
return dfs(x - kk / 2, y - kk / 2, k - 1) + value * 2;
else if (x <= kk / 2 && y > kk / 2)
return dfs(kk - y + 1, kk / 2 - x + 1, k - 1) + value * 3;
}
int main() {
IOS;
cin >> n >> k;
for (int i = 1; i <= n; ++i) {
cin >> p[i].x >> p[i].y;
p[i].value = dfs(p[i].x, p[i].y, k);
}
sort(p + 1, p + 1 + n);
for (int i = 1; i <= n; ++i)cout << p[i].x << " " << p[i].y << "\n";
return 0;
}