andrew演算法
演算法做兩次掃瞄,先從最左邊的點沿下凸包掃瞄到最右邊,再從最右邊的點沿上凸包掃瞄到最左邊,上下合在一起是完整的凸包。以下
convex_hull
函式為核心求解凸包的函式,凸包頂點放在ch
陣列中,返回值為頂點數。
//計算幾何
intsgn
(db x)
struct point;}
point operator
-(point b);}
bool
operator
==(point b)
bool
operator
<
(point b)
}p[maxn]
, ch[maxn]
;db cross
(point a, point b)
//求×積
db distance
(point a, point b)
//求凸包,凸包頂點放在ch中,返回值為頂點數
intconvex_hull
(point *p,
int n, point *ch)
int j = v;
//求上凸包
for(
int i = n -
2; i >=0;
--i)
ch[v++
]= p[i];}
v =(n >1)
? v -
1: v;
//若n>1,最左邊的多加了一次
return v;
}
以下部分求解周長,其中有一些小技巧:
1.求周長,到凸包上最後乙個頂點與首個頂點相加的處理:取餘。
distance(ch[i], ch[(i + 1)%v])
2.特判一下n
的個數。
_for
(i,0
, n);}
int v =
convex_hull
(p, n, ch)
;//凸包頂點數
db l =
0.0;
if(n ==
1) l =0;
else
if(n ==
2) l =
distance
(ch[0]
, ch[1]
);else
printf
("%.2f\n"
, l)
;
解題思路
求順時針上凸包面積最大。
注意事項
1.一開始對所有點進行排序,x
相同時,y
大的排在前面。
2.注意三點共線的情況,判斷是否能使得字典序更小。
參考**
#include
using
namespace std;
#define local
//提交的時候一定注釋
#define _for(i, a, b) for(int i = (a); i < (b); ++i)
#define _rep(i, a, b) for(int i = (a); i <= (b); ++i)
#define pb push_back
#define vi vector
#define inf 0x3f3f3f3f
#define mp make_pair
#define lowbit(x) ((x) & (-x))
typedef
long
long ll;
typedef
double db;
const db eps =
1e-8
;//定義浮點數誤差
const
int mod =
998244353
;const
int maxn =
1e6+10;
intreadint()
//計算幾何
intsgn
(db x)
struct point;}
point operator
-(point b);}
bool
operator
==(point b)
bool
operator
<
(point b)
else
return x < b.x;
}}p[maxn]
, ch[maxn]
;db cross
(point a, point b)
//求×積
db distance
(point a, point b)
bool
judge
(point a, point b, point c)
else
return
false;}
//求凸包,凸包頂點放在ch中,返回值為頂點數
intconvex_hull
(point *p,
int n, point *ch)
ch[v++
]= p[i];}
//v = (n > 1) ? v - 1 : v;
return v;
}int
main()
;}int v =
convex_hull
(p, n, ch)
;//凸包頂點數
_for
(i,0
, v)
printf
("\n");
}return0;
}
巧妙地運用凸包的一道題。
演算法競賽從入門到高階
(真的巨巨巨巨好的一本書!!!)
計算幾何凸包入門詳解
講這個之前,先說一下我自己的看法 求凸包網上有很多種方法,個人覺得最好用最常用的就是graham掃瞄法,本篇博文我也就只講這一種演算法求解凸包。講這個問題之前我們必須要弄清楚何為凸包?我來口胡一下吧,很明顯凸包這個名詞就已經給了我們乙個重要的資訊,那就是這個東西它肯定是乙個凸多邊形。那除了是凸多邊形...
計算幾何 凸包
有多個手機訊號發射器,求解乙個最小區域,要求所有的發射器都包含在這個最小區域中,並且任意兩台發射器之間的交流包含於在這個區域內。將所有的發射器看做為點,任意兩個點之間的連線都包含於乙個平面s 乙個平面的子集s 是凸的,當且僅當 s中的任意兩個點之間的連線都包含於 s中。點集 p的凸包是所有包含 p的...
計算幾何 凸包
如求凸包周長 include include include include include include using namespace std define pi 3.1415926 define eps 1e 10 class point 建立point類,裡面包含很多point的運算子 定...