平面上的最接近點對
題目描述
給定平面上 nn 個點,找出其中的一對點的距離,使得在這 nn 個點的所有點對中,該距離為所有點對中最小的。
輸入格式
第一行一個整數 nn,表示點的個數。
接下來 nn 行,每行兩個實數 x,yx,y ,表示一個點的行坐標和列坐標。
輸出格式
僅一行,一個實數,表示最短距離,四捨五入保留 44 位小數。
輸入輸出樣例
3
1 1
1 2
2 2
1.0000
說明/提示
數據規模與約定
對於 100\%100% 的數據,保證 1 ≤ n ≤ 10^41≤n≤104,0 ≤ x, y ≤ 10^9,0≤x,y≤109,小數點後的數字個數不超過 66。
分治法求解
分解
對所有的點按照 xx 坐標(或者 yy )從小到大排序(排序方法時間複雜度 O(nlogn))O(nlogn))。根據下標進行分割,使得點集分為兩個集合。
解決
遞歸的尋找兩個集合中的最近點對。取兩個集合最近點對中的最小值 min(dis_{left},dis_{right})min(disleft,disright)
合併
最近距離不一定存在於兩個集合中,可能一個點在集合 A,一個點在集合 B,而這兩點間距離小於 disdis。
其中如何合併是關鍵。根據遞歸的方法可以計算出劃分的兩個子集中所有點對的最小距離 disleft,disright,再比較兩者取最小值,即 dis=min(dis_{left},dis_{right}) 。那麼一個點在集合 A,一個在集合 B中的情況,可以針對此情況,用之前分解的標準值,即按照 x 坐標(或者 y)從小到大排序後的中間點的 x 坐標作為 mid。劃分一個 [mid-dis,mid+dis] 區域,如果存在最小距離點對,必定存在這個區域中。
之後只需要根據左邊區域 [mid-dis,mid][mid−dis,mid] 的點來遍歷右邊區域 [mid,mid+dis][mid,mid+dis] 的點,即可找到是否存在小於 disdis 距離的點對。
但是存在一個最壞情況,即通過左右兩個區域計算得到的 disdis 距離來劃分的第三區域可能包含集合所有的點,這時候進行遍歷查找,時間複雜度仍然和 brute forcebruteforce 方法相同,都為O(n^2)