-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathPOJ_3714_Raid_二维平面最近点对_分治法.cpp
94 lines (90 loc) · 1.57 KB
/
POJ_3714_Raid_二维平面最近点对_分治法.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
#include <iostream>
#include <algorithm>
#include <limits>
#include <iomanip>
using namespace std;
typedef struct point{
int x,y;
bool flag;
}point;
point parr[200005];
int psub[200005];
const double maxi=numeric_limits<double>::max();
bool cmp(point a,point b)
{
return a.x<b.x;
}
bool compare(int a,int b)
{
return parr[a].y<parr[b].y;
}
double dist(point a,point b)//返回两点间的距离
{
if(a.flag==b.flag){
return maxi;
}
return sqrt(pow(a.x-b.x,2.0)+(pow(a.y-b.y,2.0)));
}
double min_dist(int low,int high)
{
if(low==high){
return maxi;
}
if(low+1==high){
return dist(parr[low],parr[high]);
}
int mid=(low+high)>>1;
double l_min=min_dist(low,mid);
double r_min=min_dist(mid+1,high);
double mini=l_min<r_min?l_min:r_min;
int idx=0;
for(int i=mid;i>=low;--i){
if(parr[mid].x-parr[i].x<=mini){
psub[idx++]=i;
}else{
break;
}
}
for(int i=mid+1;i<=high;++i){
if(parr[i].x-parr[mid].x<=mini){
psub[idx++]=i;
}else{
break;
}
}
sort(psub,psub+idx,compare);
for(int i=0;i<idx;++i){
for(int j=i+1;j<=i+8;++j){
if(j>idx){
break;
}
if(parr[psub[j]].y-parr[psub[i]].y>mini){
break;
}
double tmp=dist(parr[psub[j]],parr[psub[i]]);
if(tmp<mini){
mini=tmp;
}
}
}
return mini;
}
int main()
{
int t;
cin>>t;
for(int i=0;i<t;++i){
int n;
cin>>n;
for(int i=0;i<n;++i){
cin>>parr[i].x>>parr[i].y;
parr[i].flag=false;
}
for(int i=n;i<2*n;++i){
cin>>parr[i].x>>parr[i].y;
parr[i].flag=true;
}
sort(parr,parr+2*n,cmp);
cout<<setiosflags(ios::fixed)<<setprecision(3)<<min_dist(0,2*n-1)<<endl;
}
}