计算几何:平面最近点对

时间:2022-11-15 23:47:25

POJ3714:求平面最近点对

寻找两个集合中的点的最近点对

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<cmath>
 4 #include<algorithm>
 5 using namespace std;
 6 const double oo=1e50;
 7 int n;
 8 double ab(double x)
 9 {
10     return x>0?x:-x;
11 }
12 struct node
13 {
14     double x,y;
15     bool bel;
16 }a[200010],temp[200010];
17 bool cx(const node &a,const node &b)
18 {
19     return a.x<b.x;
20 }
21 bool cy(const node &a,const node &b)
22 {
23     return a.y<b.y;
24 }
25 double min(double x,double y)
26 {
27     return x<y?x:y;
28 }
29 double dis(node p,node q)
30 {
31     if (p.bel==q.bel) return oo;
32     return sqrt((p.x-q.x)*(p.x-q.x)+(p.y-q.y)*(p.y-q.y));
33 }
34 double make(int l,int r)
35 {
36     if (l==r) return oo;
37     int m=(l+r)/2,i,j,k,ll,rr,p,q,x,y,z,cnt=0;
38     double ans=min(make(l,m),make(m+1,r));
39     for (i=l;i<=r;i++)
40       if (ab(a[i].x-a[m].x)<=ans)
41         temp[++cnt]=a[i];
42     sort(temp+1,temp+cnt+1,cy);
43     for (i=1;i<=cnt;i++)
44       for (j=i+1;j<=cnt;j++)
45       {
46         if (temp[j].y-temp[i].y>ans) break;
47         ans=min(ans,dis(temp[i],temp[j]));
48       }
49     return ans;
50 }
51 int main()
52 {
53     int i,j,k,T;
54     scanf("%d",&T);
55     while (T--)
56     {
57         scanf("%d",&n);
58         for (i=1;i<=n;i++)
59         {
60             scanf("%lf%lf",&a[i].x,&a[i].y);
61             a[i].bel=0;
62         }
63         for (i=1;i<=n;i++)
64         {
65             scanf("%lf%lf",&a[i+n].x,&a[i+n].y);
66             a[i+n].bel=1;
67         }
68         sort(a+1,a+2*n+1,cx);
69         printf("%.3f\n",make(1,2*n));
70     }
71 }