凸包問題——Graham掃描法

凸包(Convex Hull)是一個計(jì)算幾何(圖形學(xué))中的概念。在一個實(shí)數(shù)向量空間中礁芦,對于給定集合X堂氯,所有包含X的凸集的交集S被稱為X的凸包腺兴。X的凸包可以用X內(nèi)所有點(diǎn)(X1左电,...Xn)的凸組合來構(gòu)造。在二維歐幾里得空間中页响,凸包可想象為一條剛好包著所有點(diǎn)的橡皮圈篓足。用不嚴(yán)謹(jǐn)?shù)脑拋碇v,給定二維平面上的點(diǎn)集闰蚕,凸包就是將最外層的點(diǎn)連接起來構(gòu)成的凸多邊型栈拖,它能包含點(diǎn)集中所有的點(diǎn)。

Graham掃描法

image.png
  1. 將隨機(jī)生成的點(diǎn)放在一個平面直角坐標(biāo)系中没陡,Y 軸中最小的點(diǎn)一定是凸包上面的點(diǎn)涩哟,并以此作為坐標(biāo)的原點(diǎn)則P0。
  2. 以P0作為頂角盼玄,X 軸作為一條邊其他頂點(diǎn)與 P0 連接生成第三邊例如∠P1P0X 贴彼。
  3. 計(jì)算各個點(diǎn)相對于 P0 的幅角 α ,按從小到大的順序?qū)Ω鱾€點(diǎn)排序强岸。很容易得知 P1 和 P8 必為凸包上的點(diǎn)。當(dāng)幅角 α 相同時(shí)將靠近P0的點(diǎn)排在前面砾赔。
  4. 將凸包上的點(diǎn)入棧蝌箍,如 P1 入棧青灼,并將 P0 與棧頂元素連接如 P0-P1。判斷Pn+1 在 PO 與棧頂連線 L 的左邊還是右邊妓盲。如果在左邊或在同一直線上時(shí)即將它與棧頂元素相連杂拨,顯然 P2 與 P1連接。
  5. 將新連接線段的坐標(biāo)與前一線段坐標(biāo)進(jìn)行叉積運(yùn)算悯衬,如果叉積結(jié)果為負(fù)則必為凸包上的點(diǎn)將其入棧否則出棧弹沽,如果棧頂元素不是 幅角 α 最大的元素繼續(xù)執(zhí)行步驟4,否則結(jié)束當(dāng)前棧中元素即為凸包上的頂點(diǎn)筋粗。
  • 例如
    按步驟 4 的做法已將P1 P2 P3 連接策橘,{P1,P2}娜亿,{P2丽已,P3} 進(jìn)行叉積,所得到的結(jié)果為 + 則 P2 不是凸包上的點(diǎn)出棧买决,P3進(jìn)棧返回執(zhí)行步驟4沛婴。則需要判斷 {Pn-1,Pn} {Pn,Pn+1} 的叉積。
矢量叉積定義

矢量叉積
設(shè)有點(diǎn)p0(x0,y0),p1(x1,y1),p2(x2,y2).(p0p1),(p0p2)是共p0的兩條向量督赤,叉積d = (p0p1)x(p0p2) = (x1-x0)(y2-y0) - (x2-x0)(y1-y0)
叉積的一個非常重要性質(zhì)是可以通過它的符號判斷兩矢量相互之間的順逆時(shí)針關(guān)系:
若 d > 0 , 則(p0p1)在(p0p2)的順時(shí)針方向嘁灯。
若 d < 0 , 則(p0p1)在(p0p2)的逆時(shí)針方向。(圖示方向)
若 d = 0 , 則(p0p1)與(p0p2)共線躲舌,但可能同向也可能反向丑婿。

實(shí)現(xiàn)代碼

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<cmath>
 5 #include<stack>
 6 #include <math.h>
 7 #include <stdio.h>
 8 #include <algorithm>
 9 using namespace std;
10 struct point
11 {
12     long long  x;
13     long long  y;
14 } P[50005],S[50005];  //P 中存點(diǎn),S模擬棧存凸包的點(diǎn)孽糖;
15 
16 long long  xx;
17 long long  yy;
18 
19 // 計(jì)算各個點(diǎn)相對于 P0 的幅角 α 枯冈,按從小到大的順序?qū)Ω鱾€點(diǎn)排序。當(dāng) α 相同時(shí)办悟,距離 P0 比較近的排在前面尘奏。
20 bool cmp(struct point a,struct point b)
21 {
22     if(atan2(a.y-yy,a.x-xx)!=atan2(b.y-yy,b.x-xx))
23         return (atan2(a.y-yy,a.x-xx))<(atan2(b.y-yy,b.x-xx));
24     return a.x<b.x;
25 }
26 
27 //叉積判斷點(diǎn)的位置
28 long long  CJ(long long  x1,long long  y1,long long  x2,long long  y2)
29 {
30     return (x1*y2-x2*y1);
31 }
32 
33 long long Compare(struct point a,struct point b,struct point c)
34 {
35     return CJ((b.x-a.x),(b.y-a.y),(c.x-a.x),(c.y-a.y));
36 }
37 
38 
39 int main()
40 {
41     int n,i,j;
42     while(~scanf("%d",&n))
43     {
44         int top = 1;
45         yy = 1000000+5;
46         for(i=0;i<n;i++)
47         {
48             scanf("%lld%lld",&P[i].x,&P[i].y);
49             if(P[i].y<yy)
50             {
51                 yy = P[i].y;
52                 xx = P[i].x;
53                 j = i;
54             }
55         }
56         P[j] = P[0];
57         sort(P+1,P+n,cmp);
58         S[0].x = xx;
59         S[0].y = yy;
60         S[1] = P[1];
61         for(i = 2;i<n;)
62         {
63             if(top&&(Compare(S[top-1],S[top],P[i])<0)) top--;
64             else S[++top] = P[i++];
65         }
66         for(i=0;i<=top;i++)
67             printf("%lld  %lld\n",S[i].x,S[i].y);
68     }
69     return 0;
70 }

菜雞實(shí)現(xiàn)過程可能解釋得不通順,望請見諒病蛉。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末炫加,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子铺然,更是在濱河造成了極大的恐慌俗孝,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,110評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件魄健,死亡現(xiàn)場離奇詭異赋铝,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)沽瘦,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,443評論 3 395
  • 文/潘曉璐 我一進(jìn)店門革骨,熙熙樓的掌柜王于貴愁眉苦臉地迎上來农尖,“玉大人,你說我怎么就攤上這事良哲∈⒖ǎ” “怎么了?”我有些...
    開封第一講書人閱讀 165,474評論 0 356
  • 文/不壞的土叔 我叫張陵筑凫,是天一觀的道長滑沧。 經(jīng)常有香客問我,道長巍实,這世上最難降的妖魔是什么滓技? 我笑而不...
    開封第一講書人閱讀 58,881評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮蔫浆,結(jié)果婚禮上殖属,老公的妹妹穿的比我還像新娘。我一直安慰自己瓦盛,他們只是感情好洗显,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,902評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著原环,像睡著了一般挠唆。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上嘱吗,一...
    開封第一講書人閱讀 51,698評論 1 305
  • 那天玄组,我揣著相機(jī)與錄音,去河邊找鬼谒麦。 笑死俄讹,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的绕德。 我是一名探鬼主播患膛,決...
    沈念sama閱讀 40,418評論 3 419
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼耻蛇!你這毒婦竟也來了踪蹬?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,332評論 0 276
  • 序言:老撾萬榮一對情侶失蹤臣咖,失蹤者是張志新(化名)和其女友劉穎跃捣,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體夺蛇,經(jīng)...
    沈念sama閱讀 45,796評論 1 316
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡疚漆,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,968評論 3 337
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片娶聘。...
    茶點(diǎn)故事閱讀 40,110評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡灵临,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出趴荸,到底是詐尸還是另有隱情,我是刑警寧澤宦焦,帶...
    沈念sama閱讀 35,792評論 5 346
  • 正文 年R本政府宣布发钝,位于F島的核電站,受9級特大地震影響波闹,放射性物質(zhì)發(fā)生泄漏酝豪。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,455評論 3 331
  • 文/蒙蒙 一精堕、第九天 我趴在偏房一處隱蔽的房頂上張望孵淘。 院中可真熱鬧,春花似錦歹篓、人聲如沸瘫证。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,003評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽背捌。三九已至,卻和暖如春洞斯,著一層夾襖步出監(jiān)牢的瞬間毡庆,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,130評論 1 272
  • 我被黑心中介騙來泰國打工烙如, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留么抗,地道東北人。 一個月前我還...
    沈念sama閱讀 48,348評論 3 373
  • 正文 我出身青樓亚铁,卻偏偏與公主長得像蝇刀,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子刀闷,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,047評論 2 355

推薦閱讀更多精彩內(nèi)容

  • 一熊泵、叉積叉積的計(jì)算是線段方法的核心。對于向來p1和p2甸昏,叉積是由點(diǎn)(0,0)顽分、p1、p2和p1+p2構(gòu)成的平行四邊...
    tdeblog閱讀 867評論 0 1
  • 歸去來兮施蜜。 1.1 說明 本篇為《挑戰(zhàn)程序設(shè)計(jì)競賽(第2版)》[http://www.ituring.com.cn...
    尤汐Yogy閱讀 14,342評論 0 160
  • 你的數(shù)學(xué)直覺怎么樣卒蘸?你能憑借直覺,迅速地判斷出誰的概率大,誰的概率小嗎缸沃?下面就是 26 個這樣的問題恰起。如果你感興趣...
    cnnjzc閱讀 6,896評論 0 12
  • B樹的定義 一棵m階的B樹滿足下列條件: 樹中每個結(jié)點(diǎn)至多有m個孩子。 除根結(jié)點(diǎn)和葉子結(jié)點(diǎn)外趾牧,其它每個結(jié)點(diǎn)至少有m...
    文檔隨手記閱讀 13,224評論 0 25
  • 夏的氣息检盼,充斥著周圍的一切。攜一份清涼與平靜翘单,漫步在羊腸小道上吨枉。 烈日的炎熱自空中潑下,落在身上哄芜,汗流浹背貌亭,卻又被...
    西噥利亞噶依稀閱讀 218評論 0 0