题面
传送门
C. Points on Plane
time limit per test2 seconds
memory limit per test256 megabytes
inputstandard input
outputstandard output
On a plane are n points (xi, yi) with integer coordinates between 0 and 106. The distance between the two points with numbers a and b is said to be the following value: (the distance calculated by such formula is called Manhattan distance).
We call a hamiltonian path to be some permutation pi of numbers from 1 to n. We say that the length of this path is value .
Find some hamiltonian path with a length of no more than 25 × 108. Note that you do not have to minimize the path length.
Input
The first line contains integer n (1 ≤ n ≤ 106).
The i + 1-th line contains the coordinates of the i-th point: xi and yi (0 ≤ xi, yi ≤ 106).
It is guaranteed that no two points coincide.
Output
Print the permutation of numbers pi from 1 to n — the sought Hamiltonian path. The permutation must meet the inequality .
If there are multiple possible answers, print any of them.
It is guaranteed that the answer exists.
Examples
input
5
0 7
8 10
3 4
5 0
9 12
output
4 3 1 2 5
Note
In the sample test the total distance is:
(|5 - 3| + |0 - 4|) + (|3 - 0| + |4 - 7|) + (|0 - 8| + |7 - 10|) + (|8 - 9| + |10 - 12|) = 2 + 4 + 3 + 3 + 8 + 3 + 1 + 2 = 26
解题思路
分块思维,带有一定的贪心思想。
开始我们考虑先将X的距离优化至最短,那么就把点按坐标排序,这样最坏情况(排好序后每相邻点Y距离都是1e6)哈密顿距离和是1e12显然不行,那么再考虑分块,如果在X最短的基础上X轴每1000分成1块,在每块中再对y排序,那么每块最坏情况2e6(排好序后块中每相邻点X距离都是1e3)这样,极限哈密顿距离和是2e9<2.5e9,就可以接受了
但是实现的时候我犯了个蠢,这个根本没有X轴每1000分成1块,而是每1000点分一块,感觉数据强可能会卡掉,虽然A了,但也是侥幸,特此记录引以为戒。
错误示范
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<cstring>
using namespace std;
struct node
{
int x;
int y;
int sn;
};
bool comp1(node a, node b){
return a.x < b.x;
}
bool comp2(node a, node b){
return a.y < b.y;
}
node co[1000001];
int n;
int main(){
scanf("%d", &n);
for(int i = 0; i < n; i++){
scanf("%d%d", &co[i].x, &co[i].y);
co[i].sn = i;
}
sort(co, co+n, comp1);
int i;
for(i = 1005; i < n; i+=1005){
sort(co+i-1005, co+i, comp2);
}
sort(co+i-1005, co+n, comp2);
for(i = 0; i < n; i++){
printf("%d ", co[i].sn + 1);
}
// system("pause");
return 0;
}
正解
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<cstring>
using namespace std;
struct node
{
int x;
int y;
int sn;
};
bool comp1(node a, node b){
if(a.x==b.x)return a.y<b.y;
return a.x < b.x;
}
node co[1000001];
int n;
int main(){
scanf("%d", &n);
for(int i = 0; i < n; i++){
scanf("%d%d", &co[i].x, &co[i].y);
co[i].x/=1005;//反正块内x顺序不重要
co[i].sn = i;
}
sort(co, co+n, comp1);
for(int i = 0; i < n; i++){
printf("%d ", co[i].sn + 1);
}
// system("pause");
return 0;
}