あなたは、最寄りのポイントのペアを見つけることができます2次元平面上であなたn個の点を与えます。
[説明]
これは、パーティションの問題です。
行うことができる:
まず、昇順で行×nの点に従って。
この区間内の点はl..rに分割されている
+ 1..r再帰溶液二つの部分との中間をl..mid。
距離d1及びd2は、これら二つの点の最も近い点の内側に決定される
ので、D =分(D1、D2)
片側場合に答えの最後の点です。
左右の間隔間隔P1、P2のそれぞれの場合には、今最後の点に対する回答を検討してください。
まず、左右のセクションでは、間隔横軸を中点と点の距離dにわたって分割線を除去することができます。
次いで、P1のそれぞれについて、長さd、高い2D描画の右側の矩形。
あなたは、その矩形内右の範囲(鳩の巣原理)で、せいぜい6点を見つけます
ので、我々は唯一の昇順にy軸に応じて次のようになりl..rこの間隔行内にポイントする必要があります。
次にたい。Yが点(YD、Y + d)は座標他の検査範囲の各点(X、Y)について
、しかしケースのこの種、N-の時間複雑logN個 logN個のレベル。
我々は、各サブインターバルのために何かをする方法は、(y軸に応じて)ソートマージ、時間の合併時に答えることができる
D未満である方法によってトラバーサルとyは差の絶対値の座標、ポイント範囲左ときにマージソート他のポイント
これは、n *のLOGNの時間複雑さのレベルであります
[コード]
#include <cstdio>
#include <cmath>
using namespace std;
const int N = 1e5;
const int oo = 1e9;
struct abc{
int x,y;
};
int n;
abc a[N+10];
abc b[N+10];
int sqr(int x){return x*x;}
int dis(abc a,abc b){
return sqr(a.x-b.x)+sqr(a.y-b.y);
}
int min(int x,int y){
if (x<y) return x;else return y;
}
int divide(int l,int r){
if (l>=r) return oo;
int mid = (l+r)>>1;abc mp = a[mid];
int d = divide(l,mid);d = min(d,divide(mid+1,r));
int i = l,j = mid + 1,k = l;
while (i<=mid || j<=r){
while (j<=r && (i>mid || a[j].y<=a[i].y)) b[k++] = a[j++];
if (i<=mid && mp.x-a[i].x<d){//a[i]是分割线左边的点
//此时a[mid+1..j-1]全都小于等于a[i]的纵坐标
//a[j..r]全都大于a[i]的纵坐标。(且这两段的点都是分割线右边的点)
for (int l = j-1;l>=mid+1;l--){
if (sqr(a[i].y-a[l].y)>d) break;
int temp = dis(a[l],a[i]);
d = min(temp,d);
}
for (int l = j;l<=r;l++){
if (sqr(a[l].y-a[i].y)>d) break;
int temp = dis(a[l],a[i]);
d = min(temp,d);
}
}
if (i<=mid) b[k++] = a[i++];
}
for (int i = l;i<= r;i++) a[i] = b[i];
return d;
}
void _swap(abc *x,abc *y){
abc t = *x;
*x = *y;
*y = t;
}
void kp(abc a[],int l,int r){
abc temp = a[l];
int i = l,j = r+1;
while(true){
while (a[++i].x<temp.x && i<r);
while (a[--j].x>temp.x);
if (i>=j) break;
_swap(&a[i],&a[j]);
}
a[l] = a[j];
a[j] = temp;
if (l<j) kp(a,l,j-1);
if (j<r) kp(a,j+1,r);
}
int main(){
scanf("%d",&n);
for (int i = 1;i <= n;i++) scanf("%d%d",&a[i].x,&a[i].y);
kp(a,1,n);
double ans = sqrt(1.0*divide(1,n));
printf("%.3f\n",ans);
return 0;
}