UVA 10245 The Closest Pair Problem(平面最近点对)

来源:互联网 发布:礼券提货系统源码 php 编辑:程序博客网 时间:2024/05/28 15:59

解题思路:
分治法求平面最近点对。

将所有点排序后,最近点对的距离就是下面两者的最小值:

(1) 两点p, q 同属于左半边或右半边时点对(p, q ) 的距离;

(2) 两点p, q属于不同区域时,距离小于d的点对(p, q)的距离。

#include <iostream>#include <cstdio>#include <cstdlib>#include <cmath>#include <vector>#include <algorithm>#define LL long longusing namespace std;const int INF = 0x3f3f3f3f;const int MAXN = 10000 + 10;const double eps = 1e-6;int N;typedef pair<double, double> Point;Point A[MAXN];bool compare_y(Point a, Point b){    return a.second < b.second;}double closest_pair(Point *a, int n){    if(n <= 1) return INF;    int m = n / 2;    double x = a[m].first;    double d = min(closest_pair(a, m), closest_pair(a + m, n - m));    inplace_merge(a, a + m, a + n, compare_y);    vector<Point> b;    for(int i=0;i<n;i++)    {        if(fabs(a[i].first - x) >= d)            continue;        for(int j=0;j<b.size();j++)        {            double dx = a[i].first - b[b.size()-j-1].first;            double dy = a[i].second - b[b.size()-j-1].second;            if(dy >= d) break;            d = min(d, sqrt(dx * dx + dy * dy));        }        b.push_back(a[i]);    }    return d;}void solve(){    sort(A, A + N);    double ans = closest_pair(A, N);    if(ans >= 10000) cout << "INFINITY" << endl;    else printf("%.4lf\n", ans);}int main(){    while(scanf("%d", &N)!=EOF)    {        if(N == 0)            break;        for(int i=0;i<N;i++)            scanf("%lf%lf", &A[i].first, &A[i].second);        solve();    }    return 0;}

0 0
原创粉丝点击