P1257 平面上的最接近點對

2021-08-09 08:49:16 字數 1779 閱讀 5708

p1257 平面上的最接近點對

給定平面上n個點,找出其中的一對點的距離,使得在這n個點的所有點對中,該距離為所有點對中最小的。

輸入格式:

第一行:n;2≤n≤10000

接下來n行:每行兩個實數:x y,表示乙個點的行座標和列座標,中間用乙個空格隔開。

輸出格式:

僅一行,乙個實數,表示最短距離,精確到小數點後面4位。

輸入樣例#1:

3

1 11 2

2 2

輸出樣例#1:

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座標的順序...