最近点对

题目参考hdu 1007

基本思想:典型的分治算法,

第一步:先把点集按x坐标排序,然后以点集数组中间元素一分为二,

第二步:分别计算两部分的最小点对距离s1和s2,

第三部:合并,合并的时候在中点左右各选择距离在s(s=min(s1,s2))以内的点,遍历每个点,计算它和后续4个点的距离,找出最小值

代码
 1 #include <iostream>
 2 #include <algorithm>
 3 #include <iomanip>
 4 #include <cmath>
 5 using namespace std;
 6 
 7 struct point
 8 {
 9     double x, y;    
10 };
11 
12 bool operator <(const point & lhs, const point & rhs)
13 {
14     if (lhs.x == rhs.x)
15         return lhs.y < rhs.y;
16     return lhs.x < rhs.x;
17 }
18 
19 inline double dist(const point & lhs, const point & rhs)
20 {
21     return sqrt((lhs.y - rhs.y) * (lhs.y - rhs.y) + (lhs.x - rhs.x) * (lhs.x - rhs.x));
22 }
23 
24 point ps[100001];
25 point T[100001];
26 int n;
27 
28 double cp(int low, int high)
29 {
30     if (high - low + 1 <= 3)
31     {
32         double s = 1e20, t;
33         for (int i = low; i < high; ++i)
34         {
35             for (int j = i+1; j <= high; ++j)
36             {    
37                 t = dist(ps[i], ps[j]);
38                 if (t < s)
39                     s = t;
40             }
41         }
42         return s;
43     }
44     else
45     {
46         int mid = (high + low) / 2;
47         double x0 = ps[mid].x;
48         double s1 = cp(low, mid);
49         double s2 = cp(mid+1, high);
50         double s = min(s1, s2);
51         
52         int k = 0;
53         for (int i = low; i <= high; ++i)
54         {
55             if (fabs(ps[i].x - x0) <= s)
56             {
57                 T[k] = ps[i];
58                 k++;
59             }
60         }
61         
62         double ss = 2 * s;
63         for (int i = 0; i < k; ++i)
64         {
65             for (int j = i+1; j < min(i+4, k); ++j)
66             {
67                 double tt = dist(T[i], T[j]);
68                 if (tt < ss)
69                     ss = tt;
70             }
71         }
72         s = min(ss, s);
73         return s;
74     }
75     
76     
77 }
78 
79 int main()
80 {
81     while (scanf("%d"&n) != EOF && n != 0)
82     {
83         for (int i = 0; i < n; ++i) {
84             scanf("%lf %lf"&ps[i].x, &ps[i].y);
85         }
86 
87         sort(ps, ps + n);
88         double ss = cp(0, n-1);
89         printf("%.2lf\n", ss/2);
90     }
91     return 0;
92 }
93 

 

 

posted @ 2010-06-06 22:39  断桥残雪  阅读(159)  评论(0编辑  收藏  举报