模板 凸包 旋轉卡殼
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 }
暴力:最遠距離兩個點一定在凸包上,建立好揹包後,列舉凸包上的點就可以了
對於凸包上的點很多,暴力的話肯定是不行的了,那麼就用旋轉卡殼,只是名字聽著神奇,其實也很好理解了
旋轉卡殼:直接套模板,求直徑
1view code/********************************************
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 }
1view code/********************************************
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 }
另外還有關於凸包周長的題目
凸包問題 旋轉卡殼
1978年,m.i.shamos在 computational ceometry 中介紹了一種尋找凸多邊形直徑的線性演算法。1.支撐線 如果一條直線l,通過凸多邊形p的乙個頂點,且多邊形在這條直線的一側,稱l是p的支撐線。2.對踵 zhong,三聲 點 如果過凸包上的兩個點可以畫一對平行直線,使凸包...
旋轉卡殼 凸包的直徑
poj 2187 直接求直徑ok 多邊形的直徑被定義為多邊形上任意兩點間的最大距離的值。在多邊形上,決定直徑的點可能不止一對。事實上,如果乙個多邊形含有n個頂點,那麼就最多有 n 對 直徑點對 在。上圖所示的是乙個簡單的多邊形直徑的例項。直徑點對在圖中是被平行的切線 用紅色表示 穿過的黑點.直徑是用...
旋轉卡殼求凸包直徑
直徑即最長的兩點的距離 列舉凸包上的所有邊,對每一條邊找出凸包上離該邊最遠的頂點 用叉積 計算這個頂點到該邊兩個端點的距離,並記錄最大的值。但是注意到當我們逆時針列舉邊的時候,最遠點的變化也是逆時針的,這樣就可以不用從頭計算最遠點,而可以緊接著上一次的最遠點繼續計算。於是我們得到了o n 的演算法。...