凸包(Graham掃瞄法構建)

2021-09-25 06:01:48 字數 2929 閱讀 5792

ps:我的媽呀,心態**,好像也不太難,看各種模板看的雲裡霧裡的,真的還是自己動手敲來的好,幾乎沒多久就懂的差不多了。。。。

乙個本該寒假就該掌握的知識,居然熬了我幾個小時。。。。。。。

這一次還是很好的了解了凸包,以前看群裡學長們說,覺得好高大上,好難的樣子,仔細了解後發現其實也沒有想象中的那麼恐怖

凸包基本概念:

這就是乙個簡單的凸包:

其實凸包求法有很多種:比如卷包裹法(時間複雜度o(n*n))、graham掃瞄法(時間複雜度o(nlogn)、jarvis步進法、melkman演算法(時間複雜度o(n))

好像melkman演算法要好一點,但是graham掃瞄法更加實用,於是就找資料惡補了下:

步驟:

1、 把所有點放在二維座標系中,則縱座標最小的點一定是凸包上的點,如圖中的p0。

2、 把所有點的座標平移一下,使 p0 作為原點,如上圖。

3、 計算各個點相對於 p0 的幅角 α ,按從小到大的順序對各個點排序。當 α 相同時,距離 p0 比較近的排在前面。例如上圖得到的結果為 p1,p2,p3,p4,p5,p6,p7,p8。我們由幾何知識可以知道,結果中第乙個點 p1 和最後乙個點 p8 一定是凸包上的點。

(以上是準備步驟,以下開始求凸包)

4、 以上,我們已經知道了凸包上的第乙個點 p0 和第二個點 p1,我們把它們放在棧裡面。現在從步驟3求得的那個結果裡,把 p1 後面的那個點拿出來做當前點,即 p2 。接下來開始找第三個點:

連線p0和棧頂的那個點,得到直線 l 。看當前點是在直線 l 的右邊還是左邊。

如果在直線的右邊就執行步驟5;如果在直線上,或者在直線的左邊就執行步驟6。

5、 如果在右邊,則棧頂的那個元素不是凸包上的點,把棧頂元素出棧。執行步驟4。

6、 當前點是凸包上的點,把它壓入棧,執行步驟7。

7、 檢查當前的點 p2 是不是步驟3那個結果的最後乙個元素。是最後乙個元素的話就結束。如果不是的話就把 p2 後面那個點做當前點,返回步驟4。

granham演算法本質:

基本上就可以分為兩個部分:

1、排序:(時間複雜度o(nlogn))

排序時,有兩種排序方式:

1、極角序(目前這種排序好像比較常見):

2、水平序

2、掃瞄;(時間複雜度o(n))

掃瞄過程也就是上面步驟中逐步試探進棧出棧的過程;

雖然這些沒多久就看懂了,但是寫**時,遲遲不敢動手,如果早些嘗試,可能就不會耗這麼長時間了⑧

於是邊嘗試,邊看大牛的**最終敲成了。。。。

當然這個**是為了解決

給定若干點,求所構成的三角形面積的最大值

暴力時間複雜度o(nnn),很顯然tle

於是:通過求得凸包,然後在凸包中進行篩選,最後a了

#include

#include

#include

#include

#include

using

namespace std;

typedef

struct

point;

point p[

50010];

point result[

50010];

/**叉乘*/

double

multi

(point p1,point p2,point p0)

/**求距離*/

double

distance

(point a,point b)

/**核心*/

intcmp

(point a,point b)

intmain()

else

if(p[i]

.y==p0.y&&p[i]

.x}/**p[0]與p[t]進行交換,好方便之後的排序操作*/

swap

(p[0

],p[t]);

sort

(p+1

,p+n,cmp)

;//排序

/**掃瞄操作*/

result[0]

=p[0];

result[1]

=p[1];

result[2]

=p[2];

int top=2;

for(

int i=

3;i)//到這凸包就已經構建完成了

double s=0;

for(

int i=

0;i<=top;i++)}

}printf

("%.2f\n"

,s);

}return0;

}

可能又多掉了幾根頭髮吧

凸包問題 Graham掃瞄法

凸包點集q的凸包 convex hull 是指乙個最小凸多邊形,滿足q中的點或者在多邊形邊上或者在其內。右圖中由紅色線段表示的多邊形就是點集q 的凸包。頂點個數n 1 排序 在點集q中找最左下方的點p0,就是x座標和y座標都最小的點,其餘的點計算它們的極座標幅角,以幅角的非降序順序來排序,如果有幅角...

尋找凸包的graham 掃瞄法

1,點集q的凸包 convex hull 是指乙個最小凸多邊形,滿足q中的點或者在多邊形邊上或者在其內。2,凸包最常用的凸包演算法是graham掃瞄法和jarvis步進法。3,graham掃瞄法 首先,找到所有點中最左邊的 y座標最小的 如果y座標相同,找x座標最小的.以這個點為基準求所有點的極角 ...

凸包演算法詳解 Graham掃瞄法

凸包 給定二維平面上的點集,凸包就是將最外層的點連線起來構成的凸多邊型,它能包含點集中所有的點。如圖所示 來自wiki 步驟 1 先將點按從下向上,從左向右的順序排序。排完序的第乙個點,一定為凸包上的點,記為p0。2,計算各個點相對於 p0 的幅角 按從小到大的順序對各個點排序。當 相同時,距離 p...