【Math】最近点对

针对网上题解抄来抄去我就不吐槽了。

最近点对,经典问题,分治法。另外解题方法就不累述了,关键是要理解到在二分线那儿选择一个2d*d的矩形区域,将里面所有点再拿出来枚举一遍。

另外此代码来自挑战程设这本书。

//hdu 1007
#include<iostream>
#include<cstdio>
#include<vector>
#include<algorithm>
#include<cmath>
using namespace std;
#define inf 999999999999.0;

typedef pair<double,double> P;
P p[100000+9];
int cmp(P a,P b)
{
    return a.second<b.second;
}
double close_pair(P *a,int n)
{
    if(n<=1) return inf;
    int m=n/2;
    double x=a[m].first;
    double d=min(close_pair(a,m),close_pair(a+m,n-m));
    inplace_merge(a,a+m,a+n,cmp);

    vector<P> b;//最妙的就是这里了,不用先把点全部装入vector中
    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;
}
int main()
{
    double x,y;int n;
    while(scanf("%d",&n)!=EOF)
    {
        if(n==0) break;
        for(int i=0;i<n;i++)
            scanf("%lf%lf",&x,&y),p[i]=make_pair(x,y);
        sort(p,p+n);
        printf("%.2f\n",close_pair(p,n)*0.5);
    }
}

 

posted @ 2014-08-14 15:25  rickllyxu  阅读(162)  评论(0编辑  收藏  举报