• hdu 1007 二维最近点问题(分治法)


    最近点对可能出现的三个区域: 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 }
  • 相关阅读:
    向内的寻找
    了解潜意识
    NOI2014 Day1
    NOI2011 Day1
    NOI2012 Day2
    NOI2012 Day1
    NOI2013 Day2
    NOI2013 Day1
    拉格朗日乘数法
    NOI2015 Day2
  • 原文地址:https://www.cnblogs.com/pupil-xj/p/11567015.html
Copyright © 2020-2023  润新知