hdu1007 平面最近点对

挺那啥的......方法挺费解,不过速度还不错,整体就是先横向筛一遍,在纵向筛一遍,最后递归一直求求求。。。。。。

#include <cstdio>
#include <iostream>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#define MAXN 100005

using namespace std;
struct Point{
    double x,y;
    Point(){}
    Point(double _x,double _y):x(_x),y(_y){}
    void input(){
        scanf("%lf%lf",&x,&y);
    }
};
struct Point point[MAXN],px[MAXN],py[MAXN];
double get_dis(Point p1,Point p2){
    return sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y));
}
bool cmpx(Point p1,Point p2) {return p1.x<p2.x;}
bool cmpy(Point p1,Point p2) {return p1.y<p2.y;}
double ffcloest(int s,int e){
    if (e==s+1)
        return get_dis(px[s],px[e]);
    if (e==s+2)
        return min(min(get_dis(px[s],px[e]),get_dis(px[s+1],px[e])),get_dis(px[s],px[s+1]));
    int mid=(s+e)>>1,cnt=0;
    double ans=min(ffcloest(s,mid),ffcloest(mid+1,e));
    for (int i=s;i<=e;i++){
        if (abs(px[i].x-px[mid].x)<=ans)
            py[cnt++]=px[i];
    }
    //初筛完成
    sort(py,py+cnt,cmpy);
    for(int i=0;i<cnt;i++){
        for(int j=i+1;j<cnt;j++){
            if(py[j].y-py[i].y>=ans)
                break;
            ans=min(ans,get_dis(py[i],py[j]));
        }
    }
    return ans;
}
int main()
{
    int n;
    while (scanf ("%d",&n)!=EOF){
        if (!n) break;
        for (int i=0;i<n;i++){
            point[i].input();
            px[i]=point[i];
        }
        sort(px,px+n,cmpx);
        double dis=ffcloest(0,n-1);
        printf ("%.2f\n",dis/2.0);
    }
    return 0;
}

posted on 2016-03-24 13:16  very_czy  阅读(124)  评论(0编辑  收藏  举报

导航