hdu1007 平面新近点对
hdu1007 平面最近点对
//hdu1007 平面最近点对、
//第一次接触平面的最近点对,暴力果断过不了。
//解题思路:先按一个坐标轴进行排序比如x轴(若x坐标相同按y排序),
//用分冶按x轴把点集分成两块,找出每一块的最近点对然后合并,
//在合并过程中还要考虑由两个不同块构成的点对,
//这里比较重要的是对所要比较的点要在之前求出最小距离的基础下筛选
//代码如下 :
//PS:在这题发现了严重的问题,用#define min(a,b) (a<b? a:b)超时了好多次
//看来以后都不用这个了,还是写个函数来得快。
#include<iostream> #include<cstdio> #include<math.h> #include<algorithm> #define eps 1e-8 #define INF 1e20 using namespace std; struct point { double x,y;}; int n; point p[100002]; int temp[100002]; bool cmpx(const int &a,const int &b){return p[a].x> p[b].x;} bool cmpy(const int &a,const int &b){return p[a].y> p[b].y;} bool cmpxy(const point &a,const point &b) { if(a.x!=b.x)return a.x>b.x; else return a.y>b.y; } double Min(double a, double b) { return a < b ?a : b; } double distance(int a,int b) { return sqrt((p[a].x-p[b].x)*(p[a].x-p[b].x) +(p[a].y-p[b].y)*(p[a].y-p[b].y)); } double nearPair(int left,int right) { double dis=INF; if(left==right) return dis; if(left+1==right) return distance(left,right); int mid=(left+right)>>1; dis=Min(dis,nearPair(left,mid)); dis=Min(dis,nearPair(mid+1,right)); int i,j,k=0; for(i=left;i<=right;i++) { if(fabs(p[mid].x-p[i].x)<=dis) temp[k++]=i; } sort(temp,temp+k,cmpy); for(i=0;i<k;i++) { for(j=i+1;j<k&&fabs(p[temp[j]].y-p[temp[i]].y)<dis;j++) { dis=Min(dis,distance(temp[i],temp[j])); } } return dis; } int main() { while(scanf("%d",&n),n) { int i; for(i=0;i<n;i++) scanf("%lf%lf",&p[i].x,&p[i].y); sort(p,p+n,cmpxy); printf("%.2lf\n",nearPair(0,n-1)/2.0); } return 0; }