平面中取一定點a,從a點出發的一條射線am,再選定乙個長度單位和角度的正方向(通常取逆時針方向)。
對於平面內任意一點b,都可以用有序對(
這樣建立的座標系稱為極座標系,定點a稱為極點,射線am稱為極軸,
若極座標系中定點a與直角座標系的原點o重合,極座標系中的極軸為直角座標系x軸正半軸,於x軸逆時針成90°角為y正半軸,則空間中任意一點a在極座標系中座標(
簡單複習之後(畢竟中學已經學過了)開始學習graham-scan演算法。
grajam-scan是一種靈活的凸包演算法,其總時間複雜度僅為o(nlogn)。graham掃瞄法的原理是從點集中先找出乙個最左下方的點,可以證明,這個點肯定在凸包上(易證),然後以這個點為極點,將所有點根據與這個點的極角排序,並且同時使用乙個棧結構維護凸包上的點。
按照極角序依次將點與棧頂的兩個點拐向判斷:若右拐,則將當前點加入棧中;否則,將棧頂的點彈出。當遍歷完點集後,還在棧中的點就是凸包上的點,而且依次出棧可以得到從起點開始順時針旋轉的所有凸包上的點。
step1:選出x座標最小的點作為極點(x座標相同,選y最小的點)。這個點必在凸包上。
step2:將其餘點按極角排序,在極角相同的情況下比較與極點的距離,離極點比較近的優先。
step3:用乙個棧s儲存凸包上的點,先將按極角和極點排序最小的兩個點入棧。
step4:按需掃瞄每個點,檢查棧頂的前兩個元素與這個點構成的折線段是否「拐」向右側(叉積<=0)。
step5:如果滿足,則彈出棧頂元素,並返回step4再次檢查,直至不滿足。將該點入棧,並對其他點不斷執行step5操作。
step6:最終棧中的元素為凸包的頂點序列。
模板:輸入n個點,輸出這n個點所圍成的凸包,從原點開始順時針輸出凸包的頂點。
同樣兩份**,graham-scan掃瞄法和jarvis步進法。
code1-graham-scan掃瞄法:
//#pragma comment(linker, "/stack:1024000000,1024000000")
#include#include#include#include//#include#include#include#include#include#include#include#include#includeusing namespace std;
#define ll long long
#define pair pair//#define max(a,b) (a)>(b)?(a):(b)
//#define min(a,b) (a)
#define clean(a,b) memset(a,b,sizeof(a))// 水印
//std::ios::sync_with_stdio(false);
// register
const int maxn=1e3+10;
const int inf32=0x3f3f3f3f;
const ll inf64=0x3f3f3f3f3f3f3f3f;
const ll mod=1e9+7;
const double eps=1.0e-8;
const double pi=acos(-1.0);
struct point
friend point operator + (const point &a,const point &b)
friend point operator - (const point &a,const point &b)
friend double operator ^ (point a,point b)
};struct v
friend v operator + (const v &a,const v &b)
friend v operator - (const v &a,const v &b)
};struct circle
};point dots[maxn];
point stk[maxn];int top;
int n;
double distance(point a,point b)
double parellel(double key)
friend point operator + (const point &a,const point &b)
friend point operator - (const point &a,const point &b)
friend double operator ^ (point a,point b)
}p[maxn];
struct v
friend v operator + (const v &a,const v &b)
friend v operator - (const v &a,const v &b)
};int n,res[maxn],top;
int cmp(point a,point b)
void jarvis()
// cout<
poj-1873-the fortified forest,題解:
凸包問題 Graham Scan
graham scan 概述 對於凸多邊形的定義不在這裡做詳細敘述,這裡給出演算法的實現原理。step 1 找出x值最小的點的集合,從其中找出y值最小的點作為初始點 step 2 獲得新序列後,p n p 1 step 3 把p 0 p 1 p 2 放入乙個棧,從i 3迴圈到i n 1,取棧頂兩個元...
凸包 Graham Scan演算法
graham scan演算法是一種靈活的凸包演算法,時間複雜度是o nlogn 演算法細節 1.選出最左下角的點 排序 x最小,其次是y最小 2.其餘點按極角排序,在極角相等的情況下距離極點 p 0 最近的優先 3.用乙個棧 陣列 儲存凸包上的點,先把p 0 p 1 壓入棧。4.掃瞄每乙個點,用叉積...
Graham Scan凸包演算法
一 什麼是凸包 在乙個二維座標系中,有若干點雜亂排列著,將最外層的點連線起來構成的凸多邊型,它能包含給定的所有的點,這個多邊形就是凸包。尋找凸包的演算法有很多種,graham scan 演算法是一種十分簡單高效的二維凸包演算法,能夠在 o nlogn 的時間內找到凸包。二 graham scan 演...