最近点对
题目参考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
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