題意:簡化下題意即求凸包的周長+2×pi×r。
思路:用graham求凸包,模板是kuangbin的,演算法複雜度o(nlogn)。
ac code:
#include#include#include
#include
using
namespace
std;
const
int maxn=1005
;const
double pi=acos(-1.0
);struct
point
point(
int x,int
y):x(x),y(y){}
}list[maxn];
intstack[maxn],top;
//計算叉積p0p1×p0p2
intcross(point p0,point p1,point p2)
//計算p1p2的距離
double
dis(point p1,point p2)
//極角排序函式,角度相同則距離小的在前面
bool
cmp(point p1,point p2)
//輸入,把最左下角放在list[0],並且進行極角排序
void init(int
n) }
list[k]=list[0
]; list[
0]=p0;
sort(list+1,list+n,cmp);}//
graham掃瞄法求凸包,凸包頂點存在stack棧中
//從棧底到棧頂一次是逆時針方向排列的
//如果要求凸包的一條邊有2個以上的點
//那麼要將while中的<=改成<
//但這不能將最後一條邊上的多個點保留
//因為排序時將距離近的點排在前面
//那麼最後一條邊上的點僅有距離最遠的會被保留,其餘的會被出棧
//所以最後一條邊需要特判
//如果要求逆凸包的話需要改cmp,graham中的符號即可
void graham(int
n) top=1
; stack[
0]=0
; stack[
1]=1
;
for(int i=2;ii)
}int
main()
題意:求凸包的周長。
思路:這裡用andrew演算法來求,該演算法與graham的區別是排序方法不一樣,這裡按x座標從左到右排序,x相同的按y座標從下到上排序。下列程式展示先求下凸包,再求上凸包。複雜度o(nlogn),但據說比graham的複雜度小一點。
ac code:
#include#include#include
#include
#include
using
namespace
std;
const
int maxn=1e5+5
;struct
point
};double
cross(point p0,point p1,point p2)
//排序方法不同
bool
cmp(point a,point b)
double
dis(point a,point b)
point list[maxn],stk[maxn];
intn,p;
double
ans;
void
andrew()
stk[++p]=list[n-2
];
for(int i=n-3;i>=0;--i)
//要注意棧尾和棧頂都是list[0]
}int
main()
凸包(Graham掃瞄法構建)
ps 我的媽呀,心態 好像也不太難,看各種模板看的雲裡霧裡的,真的還是自己動手敲來的好,幾乎沒多久就懂的差不多了。乙個本該寒假就該掌握的知識,居然熬了我幾個小時。這一次還是很好的了解了凸包,以前看群裡學長們說,覺得好高大上,好難的樣子,仔細了解後發現其實也沒有想象中的那麼恐怖 凸包基本概念 這就是乙...
凸包問題 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座標最小的.以這個點為基準求所有點的極角 ...