[luogu1429]平面最接近點對(二分)

給定平面上n個點,找出其中的一對點的距離,使得在這n個點的所有點對中,該距離爲所有點對中最小的

#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstdio>
using namespace std;
int n;
struct Point{
    double x,y;
    Point(){}
    Point(double xx,double yy):x(xx),y(yy){}
};
Point p[200020],tp[200020];

bool compx(Point a,Point b){
    if(a.x != b.x)
        return a.x < b.x;
    else
        return a.y < b.y;
}
bool compy(Point a,Point b){
    return a.y < b.y;
}

double dist(Point a,Point b){
    return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
}

double fun(int l, int r){
    if(l == r)
        return 1000000000000;
    if(l + 1 == r){
        return dist(p[l],p[r]);
    }

    int mid = (l + r) / 2;
    double d1 = fun(l,mid);
    double d2 = fun(mid,r);
    double d = min(d1,d2);
    double ans = 1000000000000;
/*    int index = 0;
    for (int i = l; i <= r; ++i) {
        tp[index++] = p[i];
    }
    sort(tp,tp+index,compy);

    for (int j = 0; j < index; ++j) {
        int i = j + 1;
        while (i < index && tp[i].y - tp[j].y < d && tp[i].y - tp[j].y < ans){
            ans = min(ans,dist(tp[j],tp[i]));
            i++;
        }
    }*/

    //這也可以
    for (int i = l; i <= r; ++i) {
        tp[i] = p[i];
    }
    sort(tp + 1 + l,tp + 1 + r,compy);

    for (int j = l; j <= r; ++j) {
        for (int i = j+1; i <= r; ++i) {
            if (tp[i].y - tp[j].y < d && tp[i].y - tp[j].y < ans)
                ans = min(ans,dist(tp[j],tp[i]));
            else
                break;
        }
    }

    return min(ans,d);
}

int main() {
    scanf("%d",&n);
    for (int i = 1; i <= n; ++i) {
        scanf("%lf %lf",&p[i].x,&p[i].y);
    }
    sort(p + 1,p + n + 1,compx);
    double ans = fun(1,n);
    printf("%.4f\n",ans);
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章