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...