p1257 平面上最接近點對 (分治法)

2022-05-03 13:36:21 字數 2880 閱讀 5827

首先就是一維最接近點的情況。。。

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);

17 ans=inf;

18for( int i=0; i)

21 printf("

%f\n

",ans);

2223}24

return0;

25 }

很顯然這是暴力求解的方法。。。

但是這種方法不適合推移到二維方面,因而推薦使用分治法進行求解沒時間複雜度o(nlogn)。。。

使用分治求解:

s中的n個點為x軸上的n個實數x1,x2,...,xn。最接近點對即為這n個實數中相差最小的兩個實數。顯然可以先將點排好序,然後線性掃瞄就可以了(上述程式實現)。但我們為了便於推廣到二維的情形,為下面二維,嘗試用分治法解決這個問題。

假設我們用m點將s分為s1和s2兩個集合,這樣一來,對於所有的p(s1中的點)和q(s2中的點),有p遞迴地在s1和s2上找出其最接近點對和,並設

d = min                   

由此易知,s中最接近點對或者是,或者是,或者是某個,如下圖所示。

using

namespace

std;

7#define inf 0x3f3f3f3f

8double s[100];9

double ans=0;10

11double closest(int low,int

high)

1920

intmain()

28 printf("\n"

);29 sort(s,s+n);

30for( int i=0; i)

33 printf("\n"

);34 printf("

%.4f\n

",closest(0,n-1

));35}36

return0;

37 }

接下來二為最接近點對的情況。。。

分治:1) 把它分成兩個或多個更小的問題;

2) 分別解決每個小問題; 

3) 把各小問題的解答組合起來,即可得到原問題的解答。小問題通常與原問題相似,可以遞迴地使用分而治之策略來解決。

其實,這裡 用到了分治的思想。將所給平面上n個點的集合s分成兩個子集s1和s2,每個子集中約有n/2個點。然後在每個子集中遞迴地求最接近的點對。在這裡,乙個 關鍵的問題是如何實現分治法中的合併步驟,即由s1和s2的最接近點對,如何求得原集合s中的最接近點對。如果這兩個點分別在s1和s2中,問題就變得復 雜了。

在二維的情況下:

我們仿照一維的情況先把所有點按照x(橫座標)從左到右公升序排列.

以x橫座標中間的點作為分界線.將平面的點分成左邊和右邊,以上圖為例,分為左邊5個右邊5個.

然後找到左邊的點中最近點對的距離d1,和右邊最近點對的距離d2。

令d=min.那麼d是當前整個平面的最近點對的距離嗎?

答案不是!!

當前的d1,d2都是兩邊各自的點的最近距離,但是沒有考慮到兩邊的點相互配對的情況,即是點對乙個在左邊區域,乙個在右邊區域.

如果我們這個時候把兩邊相互配對的所有情況全部羅列出來那麼時間複雜度就變為第一種方法的o(n2).

這個時候我們便可以用上面找到的d來限制配對.即是明顯超過d的兩點不需要配對.如下:

那麼在範圍內的只有三個點,也就是說只有這個三個點相互配對的距離才可能比d小.那麼再按照方法一一樣在這些點中找到最短距離再跟d去比較.小的就是當前整個平面中所考慮的所有點中最近點對的距離。

然而在以上問題處理上,有乙個問題尚未解決就是如何找到兩邊區域中的最近點對的距離d1,d2 ?

我們可以發現在處理上面這個問題的時候,和最開始處理所有平面的點最近點距離的問題類似,只是點的數目減半了.

那麼我們可以遞迴以上問題.直到劃分的區域中只有二個或者三個點.這樣,該區域的最近點對距離就是對應的距離。這也是遞迴終止的條件。

1 #include2 #include3 #include

4 #include5 #include6

using

namespace

std;

7const

int maxn=1e4+10;8

9struct

point p[maxn];

12int

a[maxn];

1314

bool

cmpx(point a,point b)

1718

bool cmpy(int a,int

b)21

22double

dis(point a,point b)

2526

double closest(int low,int

high)38}

39 sort(a,a+cnt,cmpy);

40for( int i=0; i)45}

46return

ans;47}

4849

intmain()

55 sort(p,p+n,cmpx);

5657 printf("

%.4f\n

",closest(0,n-1

));58}59

return0;

60 }

P1257 平面上的最接近點對

p1257 平面上的最接近點對 給定平面上n個點,找出其中的一對點的距離,使得在這n個點的所有點對中,該距離為所有點對中最小的。輸入格式 第一行 n 2 n 10000 接下來n行 每行兩個實數 x y,表示乙個點的行座標和列座標,中間用乙個空格隔開。輸出格式 僅一行,乙個實數,表示最短距離,精確到...

洛谷 P1257 平面上的最接近點對

給定平面上 n 個點,找出其中的一對點的距離,使得在這 n 個點的所有點對中,該距離為所有點對中最小的。第一行乙個整數 n 表示點的個數。接下來 n 行,每行兩個實數 x,y 表示乙個點的行座標和列座標。僅一行,乙個實數,表示最短距離,四捨五入保留 4 位小數。輸入 13 1 11 2 2 2輸出 ...

平面最接近點對問題 分治

主要思想就是分治。先把n個點按x座標排序,然後求左邊n 2個和右邊n 2個的最近距離,最後合併。合併要重點說一下,比較麻煩。首先,假設點是n個,編號為1到n。我們要分治求,則找乙個中間的編號mid,先求出1到mid點的最近距離設為d1,還有mid 1到n的最近距離設為d2。這裡的點需要按x座標的順序...