p1257 平面上的最接近點對
給定平面上n個點,找出其中的一對點的距離,使得在這n個點的所有點對中,該距離為所有點對中最小的。
輸入格式:
第一行:n;2≤n≤10000
接下來n行:每行兩個實數:x y,表示乙個點的行座標和列座標,中間用乙個空格隔開。
輸出格式:
僅一行,乙個實數,表示最短距離,精確到小數點後面4位。
輸入樣例#1:
3輸出樣例#1:1 11 2
2 2
1.0000考慮以下分治演算法:n^2可以卡過洛谷測評機 但是還是分治好
設平面上的點都在點集s中,為了將s線性分割為大小大致相等的2個子集s1和s2,我們選取一垂直線l(方程:x=m)來作為分割直線。其中m為s中各點x座標的中位數。由此將s分割為s1=和s2=。從而使s1和s2分別位於直線l的左側和右側,且s=s1∪s2 。由於m是s中各點x座標值的中位數,因此s1和s2中的點數大致相等。 遞迴地在s1和s2上解最接近點對問題,我們分別得到s1和s2中的最小距離δ1和δ2。現設δ=min (δ1,δ2)。
若s的最接近點對(p,q)之間的距離d(p,q)
此時,p1中所有點與p2中所有點構成的點對均為最接近點對的候選者。在最壞情況下有n^2/4對這樣的候選者。但是p1和p2中的點具有以下的稀疏性質,它使我們不必檢查所有這n2/4對候選者。考慮p1中任意一點p,它若與p2中的點q構成最接近點對的候選者,則必有d(p,q)
由δ的意義可知p2中任何2個s中的點的距離都不小於δ。由此可以推出矩形r中最多只有6個s中的點。事實上,我們可以將矩形r的長為2δ的邊3等分,將它的長為δ的邊2等分,由此匯出6個(δ/2)×(2δ/3)的矩形。
因此d(u,v)≤5δ/6
我們只知道對於p1中每個s1中的點p最多隻需要檢查p2中的6個點,但是我們並不確切地知道要檢查哪6個點。為了解決這個問題,我們可以將p和p2中所有s2的點投影到垂直線l上。由於能與p點一起構成最接近點對候選者的s2中點一定在矩形r中,所以它們在直線l上的投影點距p在l上投影點的距離小於δ。由上面的分析可知,這種投影點最多只有6個。因此,若將p1和p2中所有s的點按其y座標排好序,則對p1中所有點p,對排好序的點列作一次掃瞄,就可以找出所有最接近點對的候選者,對p1中每一點最多只要檢查p2中排好序的相繼6個點。
至此,我們用分治法求出平面最接近點對。
1 #include 2 #include 3 #include 4 #include 5**6const
double inf=0x3f3f3fll;
7const
int maxn=200010;8
9int
n;10
11int
t[maxn];
1213
struct
node
19};
20node e[maxn];
2122 inline double cal(int i,int
j) 27
28 inline bool cmp(int x,int
y) 31
32 inline double merge(int l,int
r) 50
return
d;51}52
53int
hh()
6263
int sb=hh();
64int main(int argc,char**argv)
洛谷 P1257 平面上的最接近點對
給定平面上 n 個點,找出其中的一對點的距離,使得在這 n 個點的所有點對中,該距離為所有點對中最小的。第一行乙個整數 n 表示點的個數。接下來 n 行,每行兩個實數 x,y 表示乙個點的行座標和列座標。僅一行,乙個實數,表示最短距離,四捨五入保留 4 位小數。輸入 13 1 11 2 2 2輸出 ...
p1257 平面上最接近點對 (分治法)
首先就是一維最接近點的情況。1 include2 include3 include4 include5 using namespace std 6 define inf 0x3f3f3f3f 7double s 100 8 double ans 0 9 10int main 16 sort s,s ...
平面最接近點對問題 分治
主要思想就是分治。先把n個點按x座標排序,然後求左邊n 2個和右邊n 2個的最近距離,最後合併。合併要重點說一下,比較麻煩。首先,假設點是n個,編號為1到n。我們要分治求,則找乙個中間的編號mid,先求出1到mid點的最近距離設為d1,還有mid 1到n的最近距離設為d2。這裡的點需要按x座標的順序...