POJ 3348 Cows | 凸包模板題
阿新 • • 發佈:2017-12-13
nor clas body 模板 block ron pac ring 進行
題目:
給幾個點,用繩子圈出最大的面積養牛,輸出最大面積/50
題解:
Graham凸包算法的模板題
下面給出做法
1.選出x坐標最小(相同情況y最小)的點作為極點(顯然他一定在凸包上)
2.其他點進行極角排序<極角指從坐標軸的某一方向逆時針旋轉到向量的角度>,
極角一樣按距離從近到遠(可以用叉積實現)
3.用棧維護凸包上的點,將極點和極角序最小的點依次入棧
4.按順序掃描,檢查棧頂的前兩個元素與這個點構成的線段是否拐向右(順時針側,叉積小於0)
如果滿足就彈出棧頂元素,直到不滿足或者棧裏不足兩個元素
反之入棧
#include<cstdio> #include<algorithm> #include<cstring> #include<stack> #define N 10005 using namespace std; int n,m; struct point { int x,y; point (){}; point (int _x,int _y) { x=_x,y=_y; } point operator - (const point &a)const { return point (x-a.x,y-a.y); } int operator * (const point &a) const { return x*a.y-y*a.x; } int norm()const { return x*x+y*y; } }p[N],q[N]; bool cmp(int u,int v) { int det=(p[u]-p[1])*(p[v]-p[1]); if (det!=0) return det>0; return (p[u]-p[1]).norm() < (p[v]-p[1]).norm(); } void Graham() { int id=1; for (int i=2;i<=n;i++) if (p[i].x<p[id].x || (p[i].x==p[id].x && p[i].y<p[id].y)) id=i; if (id!=1) swap(p[1],p[id]); int per[N]; for (int i=1;i<=n;i++) per[i]=i; sort(per+2,per+1+n,cmp); q[++m]=p[1]; for (int i=2;i<=n;i++) { int j=per[i]; while (m>=2 && (p[j]-q[m-1])*(q[m]-q[m-1])>=0) m--; q[++m]=p[j]; } } int Area() { int res=0; q[m+1]=q[1]; for (int i=1;i<=m;i++) res+=q[i]*q[i+1]; return res/2; } int main() { scanf("%d",&n); for (int i=1;i<=n;i++) scanf("%d%d",&p[i].x,&p[i].y); Graham(); int ans=Area()/50; printf("%d\n",ans); return 0; }
POJ 3348 Cows | 凸包模板題