P1429 平面最近点对(加强版)

二维平面最近点

#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<cmath>
#include<string>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 2e5 + 10;
const int INF = 2e9;
int n,temp[N];
struct Point{
    double x,y;
}S[N];
bool cmp(const Point &a,const Point &b)
{
    if(a.x == b.x)
    {
        return a.y < b.y;
    }
    return a.x < b.x;
}
bool cmps(const int &a,const int &b)
{
    return S[a].y < S[b].y;
}
double dist(int i,int j)
{
    double x = pow((S[i].x - S[j].x),2);
    double y = pow((S[i].y - S[j].y),2);
//    cout << x << ' ' << y << '\n';
    return sqrt(x+y);
}
double merge(int left,int right)
{
    double d = INF;
    if(left == right)
        return d;
    if(left + 1 == right)
    {
        double dd = dist(left,right);
//        cout << left << " " << right << " " << dd << "\n";
        return dd;
    }
    int mid = (left + right) / 2;
    double d1 = merge(left,mid);
    double d2 = merge(mid+1,right);
    d = min(d1,d2);
    int k = 0;
    for(int i=left;i<=right;i++)
    {
        if(fabs(S[mid].x - S[i].x) < d)
        {
            temp[k++] = i;
        }
    }
    sort(temp,temp+k,cmps);
    for(int i=0;i<k;i++)
    {
        for(int j=i+1;fabs(S[temp[j]].y - S[temp[i]].y) < d && j < k;j++)
        {
            d = min(d,dist(temp[i],temp[j]));
        }
    }
    return d;
}
int main()
{
    cin >> n;
    for(int i=0;i<n;i++)
    {
        scanf("%lf%lf",&S[i].x,&S[i].y);
    }
    sort(S,S+n,cmp);
    printf("%0.4lf\n",merge(0,n-1));
    return 0;
}
posted @ 2020-10-01 23:19  hh13579  阅读(105)  评论(0编辑  收藏  举报