それぞれ境界として左右二つの部分、最も近いポイントのシーク距離の左右の部分に中間座標、及び次いで合わせ、x座標でソートn個の点、パーティションの使用を考えました。二つの部分の最も近い距離dについて決定され、統合プロセスは、ストリップ幅部2dは二組に属する2つの点があり、距離がdよりも小さい、最大n個の点が存在してもよいかどうかを確認する必要があり、最悪の場合の時間がマージO(N ^ 2)である。しかし、疎な性質を持つ点の左右には、左右の任意の点について、点の右側は、矩形のD * 2dと、検査及びせいぜい6内に入らなければならない下点(鳩の巣原理)yの並び順第一帯状部点座標ように、線形スキャンので、O(nlogn)の合成時の複雑。
#include <bits/stdc++.h> using namespace std; const int inf=0x3f3f3f3f; const int N=1e5+10; int n; struct Point { double x,y; } a[N],b[N]; bool cmpx(const Point a,const Point b) { return a.x<b.x; } bool cmpy(const Point a,const Point b) { return a.y<b.y; } double dis(Point a,Point b) { return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)); } double solve(int l,int r) { if (l==r) { return inf; } int mid=(l+r)>>1,tail=0; double d=min(solve(l,mid),solve(mid+1,r)); for (int i=mid; i>=l&&a[mid].x-a[i].x<d; i--) { b[tail++]=a[i]; } for (int i=mid+1; i<=r&&a[i].x-a[mid].x<d; i++) { b[tail++]=a[i]; } sort(b,b+tail,cmpy); for (int i=0; i<tail; i++) { for (int j=i+1; j<tail&&b[j].y-b[i].y<d; j++) { d=min(d,dis(b[i],b[j])); } } return d; } int main() { while (scanf("%d",&n)) { if (!n) { break; } for (int i=1; i<=n; i++) { scanf("%lf%lf",&a[i].x,&a[i].y); } sort(a+1,a+n+1,cmpx); double ans=solve(1,n)/2; printf("%.2lf\n",ans); } }