1. 程式人生 > >凸包之Andrew演算法——模板整理

凸包之Andrew演算法——模板整理

是Graham的變種。水平掃描,分別構造上下凸殼,然後把兩者接起來。
感覺比Graham好用。
複雜度O(nlog2n) (排序)

#include<cmath>
#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn=1100;
const double eps=1e-9;
int dcmp(double x){
    if(fabs(x)<eps) return 0;
    return x<0?-1:1;
}
struct Point{
    double
x,y; Point(double x=0,double y=0):x(x),y(y){} bool operator < (const Point &b)const{ if(x<b.x) return true; if(x>b.x) return false; return y<b.y; } }; typedef Point Vector; Vector operator - (Point A,Point B){ return Vector(A.x-B.x,A.y-B.y); } double
Cross(Vector A,Vector B){ return A.x*B.y-A.y*B.x; } double getDis(Point P1,Point P2){ return sqrt((P1.x-P2.x)*(P1.x-P2.x)+(P1.y-P2.y)*(P1.y-P2.y)); } int n,tot; double ans,L; Point a[maxn],ch[maxn]; int Andrew(){ sort(a,a+n); int len=0; for(int i=0;i<=n-1;i++){ while(len>1
&&dcmp(Cross(ch[len]-ch[len-1],a[i]-ch[len-1]))==-1) len--; ch[++len]=a[i]; } int k=len; for(int i=n-2;i>=0;i--){ while(len>k&&dcmp(Cross(ch[len]-ch[len-1],a[i]-ch[len-1]))==-1) len--; ch[++len]=a[i]; } return len; } int main(){ freopen("poj1113.in","r",stdin); freopen("poj1113.out","w",stdout); scanf("%d%lf",&n,&L); for(int i=0;i<=n-1;i++) scanf("%lf%lf",&a[i].x,&a[i].y); int t=Andrew(); ans=0; for(int i=1;i<=t-1;i++) ans+=getDis(ch[i],ch[i+1]); printf("%.0lf\n",ans+2*3.14159*L); return 0; }

相關推薦

Andrew演算法——模板整理

是Graham的變種。水平掃描,分別構造上下凸殼,然後把兩者接起來。 感覺比Graham好用。 複雜度O(nlog2n) (排序) #include<cmath> #include&l

Andrew演算法

凸包:通俗來講,就是能夠把集合中的點包圍在內部的凸多邊形 Andrew演算法:是Graham演算法的改進版,後者複雜度為O(nlogn),而這種演算法複雜度為O(n) 這種演算法的思想是先對座標點進行排序,規則是按X從小到大進行排序,如果X相同則按Y從小到大

計算幾何 二維問題 Andrew演算法

凸包:把給定點包圍在內部的、面積最小的凸多邊形。 Andrew演算法是Graham演算法的變種,速度更快穩定性也更好。 首先把所有點排序,按照第一關鍵字x第二關鍵字y從小到大排序,刪除重複點後得到點序列P1...Pn。 1)把P1,P2放入凸包中,凸包中的點使用棧儲存 2)從p3開始

淺談Andrew 與 Graham

前言 腦補知識點: 1.向量的內積(數量積,點乘): 公式:a· b = |a| * |b| cos<a, b>=a.x* b.y + b.x * a.y 2.向量的外積(向量積,差乘): 公式:|c|= |a|*|b|*sin<a, b> = a

平面多邊形和空間絡體演算法整理

最近畢設專案中用到了最大包絡體求算演算法,在這裡進行簡單的整理,為了以後更好的理解。 準備知識 關於點的定義 //空間上任何一個點資訊 struct Point { double x, y, z; Point(){} Point(double xx,do

-Graham-Scan演算法

(1)問題: 給定二維平面點集,求最小的包含所有點的凸多邊形。 (2)Gramham-Scan演算法: Gramham-Scan是一種靈活的凸包演算法,其總的時間複雜度僅為O(n*log(n))。 步驟: Step1: 選定x座標最小(相同情況y最小)的點作為極點,這個點必

——Graham-Scan演算法

Graham-Scan演算法是一種靈活的凸包演算法,時間複雜度是O(nlogn) 演算法細節: 1. 選出最左下角的點(排序:x最小,其次是y最小) 2. 其餘點按極角排序,在極角相等的情況下距離極點(p[0])最近的優先 3. 用一個棧(陣列)儲存凸包上的點,先把p[0]

Graham Scan演算法實現

凸包演算法實現點集合中搜索凸包頂點的功能,可以處理共線情況,可以輸出共線點也可以不輸出而只輸出凸包頂點。經典的Graham Scan演算法,點排序使用極角排序方式,並對共線情況做特殊處理。一般演算法是將共線的點去掉距離小的,保留最遠的,這樣處理會導致不能輸出凸包邊上的點,只能

的JarvisMarch演算法——Java語言

public class JarvisMarch<T extends Planarizable>{ private List<T> points; private List<T> hull; private static int

模板Andrew演算法

凸包問題的一般解法有:Graham演算法、Melkman演算法、Andrew演算法等 Andrew演算法是Graham演算法的變種。 由於Andrew演算法程式碼簡便,效率比較高,筆者更推薦使用

1113 Wall (Andrew演算法+

Once upon a time there was a greedy King who ordered his chief Architect to build a wall around the King's castle. The King was so greedy

3348 Cows(Andrew演算法+

Your friend to the south is interested in building fences and turning plowshares into swords. In order to help with his overseas adventur

二維求解(Andrew演算法

Andrew演算法是Graham演算法的變種。 其主要思想為把凸包上的點依次放入棧中, 如果發現形成了凹多邊形(叉積為負值) 就刪除一些點,使得又能夠維持凸的形態。 這時就會發現,處理各個點需要按照x從左往右的順序,排序即可 當然,這只是處理了下凸的一個凸殼,倒

基於水平序的Andrew演算法 最詳細的圖解(多圖預警)

給出凸包的定義: 簡要說一下思路: 首先將所有點按照x從小到大(x同則y從小到大)排序 把p1,p2放入凸包,從p3開始,當新點在凸包‘前進’方向的左邊時繼續,否則依次刪除最近加入凸包的點,直到新點在左邊 輸入不能有重複點,不希望凸包邊上有點可疑將<=改為<

-Andrew演算法&&Graham掃描法

凸包簡介: 在二維平面上(二維凸包)給出若干個點,能夠包含這若干個點的面積最小的凸多邊形稱為凸包(可以想像有很多個釘子釘在牆上,然後用一個橡皮圈套在所有的釘子上,最後橡皮圈形成的就是一個凸包)。 Graham掃描法: Graham掃描法是一種基於極角排序的進行求解的

演算法學習筆記計算幾何--平面

Introduction 凸包(Convex Hull)是計算幾何中的一類極其重要的問題,計算幾何中的很多問題都可以轉化為凸包問題來解決。 直觀的來講,凸包就像是在一塊釘有若干個釘子的木板上撐開一根橡皮筋來講所有釘子圍起來一樣。 構造凸包的演算法可謂汗

Cows (Andrew演算法描述,計算

Your friend to the south is interested in building fences and turning plowshares into swords. In order to help with his overseas adventure

計算幾何----Andrew演算法--HDU1392

題目描述 給出一些點,求凸包的周長。 什麼是凸包 用不嚴謹的話來講,給定二維平面上的點集,凸包就是將最外層的點連線起來構成的凸多邊型,它能包含點集中所有的點。 凸包的Andrew演算法 Andrew演算法是graham的變種。它的思想是這樣的:

codevs1298, hdu1392 (模板

叉積 pan 向量 math != 不能 p s ace iostream 題意: 求凸包周長。 總結: 測試模板。 代碼: #include <iostream> #include <cstdio> #include <cstring>

POJ 3348 Cows | 模板

nor clas body 模板 block ron pac ring 進行 題目: 給幾個點,用繩子圈出最大的面積養牛,輸出最大面積/50 題解: Graham凸包算法的模板題 下面給出做法 1.選出x坐標最小(相同情況y最小)的點作為極點(顯然他一定在凸包上) 2.