杭电 1007
来源:互联网 发布:centos安装内核开发包 编辑:程序博客网 时间:2024/05/12 19:47
//最短的两点距离#include <iostream>#include <cmath>#include <ctime>const double eps = 0.00001;struct Point{ double x; double y; int index;};const int N = 100000;//点的个数Point X[N];Point Y[N];Point C[N];double getDistance(Point a,Point b)//两点间的距离{ return sqrt(pow((a.x-b.x),2)+pow((a.y-b.y),2));}int cmp_x(const void *p, const void *q)//用于对X坐标进行排序{ double temp = ((Point*)p)->x - ((Point*)q)->x; if (temp > 0) return 1; else if (fabs(temp) < eps) return 0; else return - 1;}int cmp_y(const void *p, const void *q)//用于对Y坐标进行排序{ double temp = ((Point*)p)->y - ((Point*)q)->y; if (temp > 0) return 1; else if (fabs(temp) < eps) return 0; else return - 1;}double findCross(Point *Y,int l,int r, float x,float d){ int lcount = 0; int rcount = 0; double temp = 0; int j=(r+l)/2+1; for(int i=l;i<r;i++)//枚举所有可能,找出最小的 { for (int j = i + 1; j <= r && Y[j].y - Y[i].y < d; j++) { double temp = getDistance(Y[i], Y [j]); if (temp < d) d = temp; } } return d;}double divideConquer(Point X[],Point Y[],Point C[],int l,int r)//分治求最短距离{ if(l==r)//相等,返回无限大 { return 100000; } else if(l+1==r)//相差一时返回两点的距离 { return getDistance(X[l],X[r]); } else { int mid = (l+r)/2; for(int i=l,j=l,k=mid+1;i<=r;i++)//按X的升序存入C中 { if(Y[i].index<=mid) { C[j++] = Y[i]; } else { C[k++] = Y[i]; } } double d1=divideConquer(X,C,Y,l,mid); double d2=divideConquer(X,C,Y,mid+1,r); double d = d1>d2?d2:d1; d = findCross(C,l,r,X[mid].x,d);//求中间点的距离 return d; }}int main(){ using std::cout; using std::endl; using std::cin; int count=0; while(cin>>count&&count>0) { double distance = -1; for(int i=0;i<count;i++) { double x,y; cin>>x; cin>>y; X[i].x = x; X[i].y = y; Y[i].x = x; Y[i].y = y; } qsort(X, count, sizeof(X[0]), cmp_x);//以x轴坐标排序 for(i=0;i<count;i++) { X[i].index = i; } memcpy(Y, X, count *sizeof(X[0]));//将X复制到Y中 qsort(Y, count, sizeof(Y[0]), cmp_y);//以y轴坐标排序 distance= divideConquer(X,Y,C,0,count-1); printf("%.2lf\n",distance/2); } return 0;}