| 最近点对 | ||
|---|---|---|
| Time Limit: 1000 MS | Memory Limit: 5000 KB | |
Description
给定平面上N个点, 请找出这N个点的最近点对.
Input
第一行输入M表示包含M组测试数据,每组先输入N (N<=50000), 接着输入N个坐标(x,y), x和y均为int型整数.
Output
输出最近点对距离,精度保留2位小数
Sample Input
2 3 1 1 2 1 3 5 10 851644 996635 20388 842736 262145 615142 890041 434439 787213 89181 99282 310353 179500 803495 728862 687090 225650 604015 765534 465397
Sample Output
1.00
38153.57
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
struct position_t {
int x;
int y;
} pos[100001], tpos[100001], swappos[100001];
int n;
double mydistance(int i, int j) {
return 1.0*(pos[i].x-pos[j].x)*(pos[i].x-pos[j].x) + 1.0*(pos[i].y-pos[j].y)*(pos[i].y-pos[j].y);
}
double fun() {
double mymin = ((long long int)2)<<60;
for(int i=0; i<n-1; i++) {
for(int j=i+1; j<n; j++) {
double d = mydistance(i,j);
if(mymin > d) {
mymin = d;
}
}
}
return sqrt(mymin);
}
int cmp_xy (const void * a, const void * b) {
position_t *p1 = (position_t *)a;
position_t *p2 = (position_t *)b;
if(p1->x != p2->x) {
return p1->x - p2->x;
}
else {
return p1->y - p2->y;
}
}
int cmp_y (const void * a, const void * b) {
position_t *p1 = (position_t *)a;
position_t *p2 = (position_t *)b;
return p1->y - p2->y;
}
double divide(int low, int high) {
if(low >= high) {
return ((long long int)2)<<60;
}
if(low+1 == high) {
return mydistance(low, high);
}
int mid = (low+high)/2;
int midx = pos[mid].x;
double d1 = divide(low, mid);
double d2 = divide(mid+1, high);
double mymin = d1>d2 ? d2 : d1;
int k = 0;
for(int i=low; i<=high; i++) {
if(abs(midx-pos[i].x) < mymin) {
tpos[k].x = pos[i].x;
tpos[k].y = pos[i].y;
k++;
}
}
qsort(tpos, k, sizeof(position_t), cmp_y);
for(int i=0; i<k-6; i++) {
for(int j=1; j<=6; j++) {
double temp = 1.0*(tpos[i].x-tpos[i+j].x)*(tpos[i].x-tpos[i+j].x) + 1.0*(tpos[i].y-tpos[i+j].y)*(tpos[i].y-tpos[i+j].y);
if(temp < mymin) {
mymin = temp;
}
}
}
return mymin;
}
int solve() {
scanf("%d", &n);
for(int i=0; i<n; i++) {
scanf("%d%d", &pos[i].x, &pos[i].y);
}
//printf("%.2lf\n", fun());
qsort(pos, n, sizeof(position_t), cmp_xy);
printf("%.2lf\n", sqrt(divide(0, n-1)));
}
int main() {
int m;
scanf("%d", &m);
for(int i=0; i<m; i++) {
solve();
}
}