模板 凸包 旋轉卡殼

2022-07-17 17:12:14 字數 3652 閱讀 2431

模板  凸包  旋轉卡殼

lrj 《訓練指南》 p272

對於個點按照 x 從小到大排序,再按照 y 點從小到大排序,刪除重複的點後,得到序列 p0,p1,p2...,

把 p0 和 p1 放入凸包。 從p2開始,當新點在凸包「前進」方向的左邊時繼續,否則依次刪除最近加入凸包的點,直到新點在左邊

ps:判斷用叉積即可

2計算凸包,輸入點陣列 p, 個數為 n , 輸出點陣列 ch. 函式返回凸包頂點數

3輸入不能有重複點。函式執行完之後輸入點的順序被破壞

4如果不希望在凸包的邊上有輸入點,把兩個 <= 改成 < 【== 表示兩向量共線】

5在精度要求高時建議用 dcmp 比較67

const double eps = 1e-10;

8int dcmp(double x)913

*******************************************

*/14

double convexhull(point* p, int n, point* ch) /*

* 基於水平的andrew演算法求凸包

*/15

24int k =m;

25for(int i = n-2; i >= 0; i--) /*

*從後往前找,求"上凸包" 形成完整的封閉揹包

*/26

30if(n > 1) m--; /*

* 起點重複

*/31

return

m;32}33

34旋轉卡殼模板:

3536

盜版的別人部落格的模板,下面會貼上大牛的關於這個演算法的分析,一般是能看懂的了,如果不能看懂的,記住就好了

3738

39int rotating_calipers(point *ch, int m) /*

*旋轉卡殼模板

*/40

51return ans;/*

*返回的也就是凸包的直徑

*/52 }

暴力:最遠距離兩個點一定在凸包上,建立好揹包後,列舉凸包上的點就可以了

對於凸包上的點很多,暴力的話肯定是不行的了,那麼就用旋轉卡殼,只是名字聽著神奇,其實也很好理解了

旋轉卡殼:直接套模板,求直徑

1

/********************************************

2題意:給你 n 個點, 求所有點中最遠兩點距離

3演算法:凸包+暴力

4思路:最遠距離兩個點一定在凸包上,建立好揹包後,列舉凸包上的點就可以了

5********************************************

*/6 #include7 #include8 #include

9 #include10

using

namespace

std;

1112

const

int maxn = 50000+10;13

intn,m;

1415

struct

point;

18 point(double _x, double

_y)19

2324 point operator - (const point & b) const

2528

}p[maxn], ch[maxn];

2930

bool

cmp(point p1, point p2)

3135

36int squardist(point a, point b) /*

*距離的平方

*/37

4041

double cross(point a, point b) /*

*叉積*/

4245

46void convexhull() /*

* 求凸包

*/47

56int k =m;

57for(int i = n-2; i >= 0; i--) /*

*從後往前找"上凸包", 形成完整的封閉揹包

*/58

62if(n > 1) m--; /*

* 起點重複

*/63}64

65int

main()

6680

return0;

81 }

view code

1

/********************************************

22187 accepted 972k 297ms c++ 1927b 2013-07-27 13:38:35

3題意:給你 n 個點, 求所有點中最遠兩點距離

4演算法:凸包+旋轉卡殼

5思路:最遠距離兩個點一定在凸包上,建立好揹包後,直接套用旋轉卡殼找直徑

6********************************************

*/7 #include8 #include9 #include

10 #include11

using

namespace

std;

1213

const

int maxn = 50000+10;14

intn,m;

1516

struct

point;

19 point(double _x, double

_y)20

2425 point operator - (const point & b) const

2629

}p[maxn], ch[maxn];

3031

bool

cmp(point p1, point p2)

3236

37int squardist(point a, point b) /*

*距離的平方

*/38

4142

double cross(point a, point b) /*

*叉積*/

4346

47void convexhull() /*

* 基於水平的andrew演算法求凸包

*/48

57int k =m;

58for(int i = n-2; i >= 0; i--) /*

*從後往前找, 形成完整的封閉揹包

*/59

63if(n > 1) m--;64}

6566

int rotating_calipers() /*

*旋轉卡殼模板

*/67

77return

ans;78}

7980

intmain()

8192

return0;

93 }

view code

另外還有關於凸包周長的題目

凸包問題 旋轉卡殼

1978年,m.i.shamos在 computational ceometry 中介紹了一種尋找凸多邊形直徑的線性演算法。1.支撐線 如果一條直線l,通過凸多邊形p的乙個頂點,且多邊形在這條直線的一側,稱l是p的支撐線。2.對踵 zhong,三聲 點 如果過凸包上的兩個點可以畫一對平行直線,使凸包...

旋轉卡殼 凸包的直徑

poj 2187 直接求直徑ok 多邊形的直徑被定義為多邊形上任意兩點間的最大距離的值。在多邊形上,決定直徑的點可能不止一對。事實上,如果乙個多邊形含有n個頂點,那麼就最多有 n 對 直徑點對 在。上圖所示的是乙個簡單的多邊形直徑的例項。直徑點對在圖中是被平行的切線 用紅色表示 穿過的黑點.直徑是用...

旋轉卡殼求凸包直徑

直徑即最長的兩點的距離 列舉凸包上的所有邊,對每一條邊找出凸包上離該邊最遠的頂點 用叉積 計算這個頂點到該邊兩個端點的距離,並記錄最大的值。但是注意到當我們逆時針列舉邊的時候,最遠點的變化也是逆時針的,這樣就可以不用從頭計算最遠點,而可以緊接著上一次的最遠點繼續計算。於是我們得到了o n 的演算法。...