O(nlogn)算法详解参考此博客
时间复杂度证明参考此博客
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
const int N=2e5+4;
const double INF=1e100;
int n;
struct Point {
double x,y;
friend bool operator <(const Point &a,const Point &b) {
return a.x<b.x;
}
}p[N],t[N];
inline double dis(Point a,Point b) {
return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
inline void smin(double &x,double y) {
x=x>y?y:x;
}
inline double Abs(double x) {
return x>0?x:-x;
}
inline void Swap(Point *a,Point *b) {
Point t;
t=*a,*a=*b,*b=t;
}
inline double divide(int l,int r) {
if (l==r) return INF;
int mid=l+r>>1;
double tx=p[mid].x;//save p[mid].x since mid would change later!
double ret=min(divide(l,mid),divide(mid+1,r));
int p1=l,p2=mid+1;
int tot=0;
while (p1<=mid||p2<=r) {
if (p2<=r&&(p[p1].y>p[p2].y||p1>mid)) t[tot++]=p[p2++];
else t[tot++]=p[p1++];//(p2>r||(p[p1].y<=p[p2].y&&p1<=mid))
}
for (int i=0;i<tot;++i) p[l+i]=t[i];
for (int i=1;i<tot;++i) {
if (Abs(t[i].x-tx)>=ret) continue;
for (int j=i-1;~j&&t[i].y-t[j].y<ret;--j)
smin(ret,dis(t[i],t[j]));
}
return ret;
}
int main() {
// freopen("in2.txt","r",stdin);
scanf("%d",&n);
for (register int i=1;i<=n;++i) scanf("%lf%lf",&p[i].x,&p[i].y);
sort(p+1,p+n+1);
printf("%.4lf\n",divide(1,n));
return 0;
}