1. 程式人生 > >2018.09.30【POJ3348】Cows(凸包)(三角剖分)

2018.09.30【POJ3348】Cows(凸包)(三角剖分)

傳送門

解析:

讀優沒有寫負數又被卡了半個小時。。。
這裡採用JarrisJarris步進法求凸包。。主要講一講怎麼求多邊形面積。

思路:

滿足題意的顯然是這些點的凸包,而我們要做的就是求出凸包面積。

那麼怎麼求多邊形面積?

考慮三角剖分,我們將多邊形由一個頂點發射出的所有對角線將該多邊形剖分成若干個三角形。我們求每一個三角形的面積就是求多邊形面積了。

好的問題就變成了怎麼求三角形的面積。。。

我們還是不求三角形面積,改為求平行四邊形面積。

求平行四邊形面積就直接向量叉積就好了啊,證明什麼的我才不會寫

要證明的在評論區留言,我就抽空補了。

程式碼:

#include<cstdio>
#include<algorithm> #include<cctype> #include<cmath> #include<iostream> using namespace std; #define ll long long #define re register #define gc getchar #define pc putchar #define cs const inline int getint(){ re int num; re char c; re bool f=0; while(!isdigit(c=gc()))f^
=c=='-';num=c^48; while(isdigit(c=gc()))num=(num<<1)+(num<<3)+(c^48); return f?-num:num; } cs int N=10002; struct Point{ int x,y; Point(int _x=0,int _y=0):x(_x),y(_y){} Point operator+(cs Point &b)cs{return Point(x+b.x,y+b.y);} Point operator-(cs Point &b)cs{return Point(x-b.x,
y-b.y);} Point operator*(cs int &b)cs{return Point(x*b,y*b);} int operator*(cs Point &b)cs{return x*b.y-y*b.x;} int dot()cs{return x*x+y*y;} friend int dot(cs Point &a,cs Point &b){return a.x*b.x+a.y*b.y;} friend int cross(cs Point &a,cs Point &b){return a.x*b.y-a.y*b.x;} }O,q[N]; inline int dist(cs Point &a){ return sqrt(a.dot()); } inline int dist(cs Point &a,cs Point &b){ return sqrt((a-b).dot()); } inline bool cmp(cs Point &a,cs Point &b){ return a.x==b.x?a.y<b.y:a.x<b.x; } struct Polygon{ Point p[N]; int n; Polygon convex_hull(Point *q,int m){ sort(q+1,q+m+1,cmp); n=0; for(int re i=1;i<=m;++i){ while(n>=2&&cross(q[i]-p[n-1],p[n]-p[n-1])>=0)--n; p[++n]=q[i]; } int k=n; for(int re i=m;i>=1;--i){ while(n>k&&cross(q[i]-p[n-1],p[n]-p[n-1])>=0)--n; p[++n]=q[i]; } if(m>1)--n; return *this; } int area(){ int res=0; for(int re i=2;i<=n;++i)res+=(p[i]-p[1])*(p[i-1]-p[1]); return abs(res)/2; } }poly; int m; signed main(){ m=getint(); for(int re i=1;i<=m;++i)q[i].x=getint(),q[i].y=getint(); poly.convex_hull(q,m); cout<<poly.area()/50; return 0; }