最近点对可能出现的三个区域: SL 、SR、L两侧(L-d ~ L+d) 其中d为SL SR 中的最近点距离
图片来源:https://www.cnblogs.com/AdaByron/archive/2011/10/07/2200966.html
以下代码参照:https://blog.csdn.net/u011523796/article/details/41593511
1 #include<algorithm> 2 #include<cstdio> 3 #include<cmath> 4 #include<cstring> 5 using namespace std; 6 7 const int N = 100005; 8 9 typedef struct TagPoint { 10 double x, y; 11 int index; 12 } Point; 13 14 Point a[N], b[N], c[N]; 15 16 bool cmp_x(const Point a, const Point b) { 17 return a.x < b.x; 18 } 19 20 bool cmp_y(const Point a, const Point b) { 21 return a.y < b.y; 22 } 23 24 double dis(Point p, Point q) { 25 double x1 = p.x - q.x, y1 = p.y - q.y; 26 return sqrt(x1*x1 + y1*y1); 27 } 28 29 void merge(Point b[], Point c[], int l, int m, int r) {//归并操作 30 int i = l; 31 int p1 = l, p2 = m+1; 32 while(p1 <= m && p2 <= r) { 33 b[i++] = c[p1].y < c[p2].y ? c[p1++] : c[p2++]; 34 } 35 while(p1 <= m) b[i++] = c[p1++]; 36 while(p2 <= r) b[i++] = c[p2++]; 37 memcpy(c+l, b+l, (r-l+1)*sizeof(Point)); 38 } 39 40 double closest(Point a[], Point b[], Point c[], int l, int r) { 41 if(r - l == 1) return dis(a[l], a[r]); 42 if(r - l == 2) { 43 double x1 = dis(a[l], a[r]); 44 double x2 = dis(a[l+1], a[r]); 45 double x3 = dis(a[l], a[l+1]); 46 if(x1 < x2 && x1 < x3) return x1; 47 else if(x2 < x3) return x2; 48 else return x3; 49 } 50 int mid = (l+r)/2; 51 int i, j, k; 52 for(i = l, j = l, k = mid+1; i <= r; ++i) { 53 if(b[i].index <= mid) c[j++] = b[i]; 54 else c[k++] = b[i]; 55 } 56 double d1 = closest(a, c, b, l, mid);//次操作会使”b的值“改变,因此60行要通过c还原b; 57 double d2 = closest(a, c, b, mid+1, r); 58 double dm = min(d1, d2); 59 60 merge(b, c, l, mid, r); 61 for(i = l, k = l; i <= r; ++i) { 62 if(fabs(b[i].x - b[mid].x) < dm) { 63 c[k++] = b[i]; 64 } 65 } 66 for(i = l; i != k; ++i) { 67 for(j = i+1; j != k && c[j].y - c[i].y < dm; ++j) { 68 double temp = dis(c[i], c[j]); 69 if(temp < dm) dm = temp; 70 } 71 } 72 return dm; 73 } 74 75 int main() { 76 int n; 77 while(scanf("%d", &n) == 1 && n) { 78 for(int i = 0; i != n; ++i) { 79 scanf("%lf%lf", &a[i].x, &a[i].y); 80 } 81 sort(a, a+n, cmp_x); 82 for(int i = 0; i != n; ++i) { 83 a[i].index = i;//a存点按横坐标升序后的排列 84 } 85 memcpy(b, a, sizeof(a)); 86 sort(b, b+n, cmp_y);//b存点按纵坐标升序后的排列 87 printf("%.2lf ", closest(a, b, c, 0, n-1) / 2); 88 } 89 return 0; 90 }