最簡單的思想是直接進行遍歷,也就是n*(n-1)的複雜度;
如果採用分治的思想會簡單很多;
看了好幾篇blog,發現都不怎麼講人話,其實本質上是通過一維分治推出來的;
對於一維數軸下找最近兩點,可以按照座標點進行分治;
直接遞迴二分區域,使得細分為左右各有乙個點或者兩個點的區域;
但是有可能發生以上的情況:
左半邊區域s1最小距離位p1~p2的距離;
右半邊區域s2最小距離位q1~q2的距離;
但是對於臨近分界點會有p3~q3最小,也就是二分之後的區間合併區域;
所以可以看到,對於遞迴分治求s1和s2之後,如果需要合併,要在求三者區域的最小值;
對於p3~q3,可以尋找分界點即可,即使點mid~點mid+1,因為函式遞迴以點的個數為單位,事先進行排序;
總的呼叫情況位charge(left,mid,mid+1,right);
對於二維情況下,發生了一些變化。
對於細分計算距離,還是利用二分,使得左右點為乙個或者兩個,之後進行層層整體合併;
仍然比較的使三個距離:
1.左半邊區域s1最小距離位p1~p2的距離;
2.右半邊區域s2最小距離位q1~q2的距離;
3.處於不同集合的p3~q3的距離;
但是問題處在第三步;
由於1,2相當於直接算兩點距離,所以不涉及迭代問題;
對於二維平面下,計算則不是那麼簡單,很多blog都提到再次細分矩陣的屁話,但是都沒有解釋為神馬要細分;
對於上述合併過程,先求得left-mid和mid-right中的最小dmin,也就是前兩種情況得最小值;
然後對先對mid點左右x-dmin和x+dmin得距離進行搜尋,找到範圍內的點;
之後看兩點縱座標是否滿足相差小於dmin,如果滿足,再計算距離;
這裡最讓人不能理解的有兩點:
1.為神馬按照dmin得範圍來找;
其實細細想一下,我們最主要的目標是找到跨邊界得兩點距離小於dmin,那麼根據勾股定理,則可以明顯的知道:
對於c=a^2+b^2,c就是我們要找的最短距離,則如果a,b有乙個大於等於dmin,則距離必定大於dmin;
2.為什麼要把中心點定位mid:
合併思想使然,如果不定位mid,則會轉化為左右半邊得最小問題,也就是第一第二步得求解過程;
並且mid在**過程中屬於中介點,對於極端情況下,可以把所有潛在得兩個分處不同子集得極端情況包含進去;
例如,mid點左右區域為2d,但是左右子集各有一點,如果距離小於d,極端情況下甚至水平,都能被包含進去;
典型題目:
針對於該題目**:
#include#include#include
using
namespace
std;
struct
point ;
const
int maxn = 100100
;const
double inf = 10000000
;int
n;point num[maxn];
bool
cmp1(point a, point b)
bool cmp2(int a, int
b) double cnt(int a, int
b) double charge(int l, int
r)
int mid = (r + l) / 2
;
double d1 =charge(l, mid);
double d2 = charge(mid + 1
, r);
double d =min(d1, d2);
//進行合併計算;
vectorvec;
for (int i = l; i <= r; i++)
}sort(vec.begin(), vec.end(), cmp2);
for (int i = 0; i < vec.size(); i++)
}returnd;}
intmain()
sort(num, num +n, cmp1);
printf(
"%.2lf\n
", charge(0, n - 1) / 2
); }
return0;
}
平面幾何最近兩點(分治 sort)
本題是問station和agent之間最近的兩個,不妨先想想如果是x y平面內最近的兩點怎麼算呢。先按x座標公升序排,如果x相同,那麼y小的排到前面 之後就開始分治了 divide l,r l,r 區間內的最近點對。問題可以再縮小,考慮d1 l,mid 內的最近點對 和d2 mid 1,r 內的最近...
平面中最近的兩點(分治法)
設平面上的點按x排序好了,這樣最多增加o n logn 這再整個演算法來看並沒有增加複雜度級別。排好序後,可以劃一條垂線,把點集分成兩半 pl和pr。於是最近點對或者在pl中,或者在pr中,或者pl,pr各有一點。把三種距離情況定義為dl,dr,dc.其中dl,dr可以遞迴求解,於是問題就變為計算d...
平面最近點對問題
平面最近點對問題正如其名,給定平面上的 n 個點,找出其中的一對點,使得這對點的距離在所有點對中最小。首先顯而易見地我們可以得到這個問題的 o n 2 演算法,列舉所有點對即可。但是很顯然我們可以注意到,這裡面有很多點對顯然不是最優的,那麼我們可以想到一種剪枝方法,就是將只對x座標差值小於當前已知最...