- 分治法,将所有点按x坐标进行排序,然后左右两半的点分别递归解决
- 考虑左边的点和右边的点的距离对答案产生的贡献:首先左右两半点分边计算得到的距离最小值为dis。显然只需要考虑和\(P_{mid}\)的x坐标相差不超过dis的点,对于这些点中的任意一点i,显然只需要考虑和i的y表座相差不超过dis的点,可以证明对于每一个点i这样的点数量不超过6。
- 时间复杂度为\(O(n*logn)\)
bool cmpx(Point a,Point b){
return a.x<b.x;
}
bool cmpy(Point a,Point b){
return a.y<b.y;
}
double getDis(int l,int r,vector<Point>&v){
if(l==r)return INF;
else if(r==l+1)return dist(v[l],v[r]);
int mid=(l+r)>>1;
double dis=min(getDis(l,mid,v),getDis(mid+1,r,v));
vector<Point>temp;
for(int i=l;i<=r;i++){
if(fabs(v[i].x-v[mid].x)<=dis)
temp.push_back(v[i]);
}
sort(temp.begin(),temp.end(),cmpy);
for(int i=0;i<temp.size();i++){
for(int j=i+1;j<temp.size()&&temp[j].y-temp[i].y<dis;j++){
dis=min(dis,dist(temp[i],temp[j]));
}
}
return dis;
}
double minDis(vector<Point> v){
sort(v.begin(),v.end(),cmpx);
int l=0,r=v.size()-1;
return getDis(l,r,v);
}