The Closest Pair Problem UVA - 10245 (平面上的点分治plane of divide-and-conquer method)

传送门

题解:最近点对问题,使用平面上的点分治思想

因为n比较大,所以枚举所有点是行不通的,考虑基于分治算法的思想

假设把所有的点按x坐标分成了左右两半,那么最近点对的距离就是下面二者的最小值

1.2点p和q同属于左半边或者右半边时点对(p,q)的距离

2.2点p和q属于不同区域时点对(p,q)的距离(这里还有很多优化处理)

复杂度分析:递归的深度为O(logn),而每一层有O(n)个操作,所以总的复杂度是O(nlogn)。

#include<bits/stdc++.h>

using namespace std;

typedef pair<double,double>P;

const int MAXN=1e4+50;
const int INF=1e4+30;

int N;
P A[MAXN];

bool compare_y(P a,P b)
{
    return a.second<b.second;
}

double closest_pair(P *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));
    sort(a,a+n,compare_y);
    vector<P>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){
        printf("INFINITY\n");
    }else{
        printf("%.4f\n",ans);
    }
}

int main()
{
    while(scanf("%d",&N)!=EOF&&N){
        for(int i=0;i<N;i++){
            scanf("%lf%lf",&A[i].first,&A[i].second);
        }
        solve();
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/zhouzi2018/article/details/82794903
今日推荐