poj 3348 Cows 凸包模板题
来源:互联网 发布:免费cms源代码php 编辑:程序博客网 时间:2024/06/05 18:50
题意:给定n个点,求这n个点构成的凸包的面积。
题解:典型的凸包模板题。先求m个点组成的凸包,然后根据凸包上的一个点,将凸包分成m-2个三角形,面积就是m-2个三角形之和。三角形面积等于两条边的叉积/2.
凸包求法讲解:
1)先将点根据横坐标从小到大排序
2)然后需要了解叉积。根据两个向量的叉积,我们可以知道一条边是在另一条边的上方还是下方。
3)接着先求凸包的下半部分。遍历点,每新进来一个点,跟已求得的凸包边比较,用叉积Cross(ch[m-1]-ch[m-2],p[i]-ch[m-2]),判断新加点是在已成凸包的外面还是里面。若是在外面,则删除所有边,当边向量和该边的起点到新增点所称向量叉积小于0,即删除在凸包内的点;将新增点加入到凸包数组中,形成新的凸包。以此类推得到凸包下边。
具体过程如下图所示,开始P1,P2,P3,P4,P6都在凸包数组中,现在加入P7;由于P4P6在P4P7上方(用叉积判),所以删除P6;由于P3P4在P3P7上方,所以删除P4;由于P2P3在P2P7下方,所以停止删除,将P7加入到凸包数组中,得到新的凸包数组P1,P2,P3,P7。接着遍历下一个点,如此反复,直到遍历所有的点,就可以得到凸包的下半部分了。
4)跟3)同理得到凸包上边,最后得到的数组就是凸包了。
代码:
#include <cstdio>#include <cstdlib>#include <cmath>#include <cstring>#include <iostream>#include <algorithm>#include <map>#include <set>#include <queue>using namespace std;//基础点和向量运算struct Point{ double x,y; Point(double x=0,double y=0):x(x),y(y){}};typedef Point Vector;Vector operator + (Vector A,Vector B){return Vector(A.x+B.x,A.y+B.y);}Vector operator - (Vector A,Vector B){return Vector(A.x-B.x,A.y-B.y);}Vector operator * (Vector A,double p){return Vector(A.x*p,A.y*p);}Vector operator / (Vector A,double p){return Vector(A.x/p,A.y/p);}bool operator <(const Point& a, const Point& b){ return a.x<b.x||(a.x==b.x&&a.y<b.y);}const double eps=1e-10;int dcmp(double x)//判断正负,或者等于0{ if(fabs(x)<eps)return 0;else return x<0?-1:1;}bool operator==(const Point& a,const Point &b){ return dcmp(a.x-b.x)==0&&dcmp(a.y-b.y)==0;}double Dot(Vector A, Vector B){return A.x*B.x+A.y*B.y;}//点积double Length(Vector A){return sqrt(Dot(A,A));}//OA长double Angle(Vector A,Vector B){return acos(Dot(A,B)/Length(A)/Length(B));}//OA和OB的夹角double Cross(Vector A,Vector B){return A.x*B.y-A.y*B.x;}//叉积double Area2(Point A,Point B,Point C){return Cross(B-A,C-A);}//三角形面积Vector Rotate(Vector A,double rad)//rad为弧度,旋转rad度{ return Vector(A.x*cos(rad)-A.y*sin(rad),A.x*sin(rad)+A.y*cos(rad));}Vector Normal(Vector A)//A的单位法向量,A不能为零向量{ double L=Length(A); return Vector(-A.y/L,A.x/L);}//点和直线//P+tv表示一条直线,P为点,tv为方向向量Point GetLineIntersection(Point P,Vector v,Point Q,Vector w)//求直线交点,确保存在交点,即Cross(v,w)非0{ Vector u=P-Q; double t=Cross(w,u)/Cross(v,w); return P+v*t;}double DistanceToLine(Point P,Point A,Point B)//P点到直线AB的距离{ Vector v1=B-A,v2=P-A; return fabs(Cross(v1,v2)/Length(v1));}double DistanceToSegment(Point P,Point A,Point B)//点P到线段AB的距离{ if(A==B)return Length(P-A); Vector v1=B-A,v2=P-A,v3=P-B; if(dcmp(Dot(v1,v2))<0)return Length(v2); else if(dcmp(Dot(v1,v3))>0)return Length(v3); else return fabs(Cross(v1,v2)/Length(v1));}Point GetLineProjection(Point P,Point A,Point B)//点在直线上的投影{ Vector v=B-A; return A+v*(Dot(v,P-A)/Dot(v,v));}bool SegmentProperIntersection(Point a1,Point a2,Point b1,Point b2)//判断线段相交,不在端点相交{ double c1=Cross(a2-a1,b1-a1),c2=Cross(a2-a1,b2-a1),c3=Cross(b2-b1,a1-b1),c4=Cross(b2-b1,a2-b1); return dcmp(c1)*dcmp(c2)<0&&dcmp(c3)*dcmp(c4)<0;}bool OnSegment(Point p,Point a1,Point a2)//判断点是否在线段上(不包括端点){ return dcmp(Cross(a1-p,a2-p))==0&&dcmp(Dot(a1-p,a2-p))<0;}//多边型double ConvexPolygonArea(Point* p,int n)//多边形面积,,点按顺序{ double area=0; for(int i=1;i<n-1;i++) area+=Cross(p[i]-p[0],p[i+1]-p[0]); return area/2;}int ConvexHull(Point *p,Point *ch,int n)//求凸包{ sort(p,p+n); int i,m=0,k; for(i=0;i<n;i++) { while(m>1&&Cross(ch[m-1]-ch[m-2],p[i]-ch[m-2])<=0)m--; ch[m++]=p[i]; } k=m; for(i=n-2;i>=0;i--) { while(m>k&&Cross(ch[m-1]-ch[m-2],p[i]-ch[m-2])<=0)m--; ch[m++]=p[i]; } if(n>1)m--; return m;}const int maxn=1e4+10;Point p[maxn],ch[maxn];int n;int main(){ while(scanf("%d",&n)!=EOF) { int i,j,k,m; for(i=0;i<n;i++) scanf("%lf%lf",&p[i].x,&p[i].y); m=ConvexHull(p,ch,n); double ans; ans=ConvexPolygonArea(ch,m); printf("%d\n",(int)(ans/50.0)); } return 0;}
0 0
- poj 3348 Cows 凸包模板题
- [POJ 3348] Cows 凸包模板
- POJ 3348 Cows(凸包)
- POJ 3348 Cows (凸包)
- POJ 3348 Cows(凸包面积)
- Poj 3348 Cows (凸包面积)
- POJ 3348 Cows (凸包面积)
- POJ 3348 Cows (凸包面积)
- POJ 3348 Cows(凸包+多边形面积)
- POJ 3348 Cows(凸包面积)
- POJ 3348 Cows(凸包面积)
- POJ 3348:Cows 凸包+多边形面积
- POJ 3348 Cows (凸包面积)
- poj 3348 Cows (凸包面积)
- POJ 3348 Cows (凸包面积)
- poj3348 Cows【凸包模板】
- POJ 3348 Cows 寻找凸包 凸包面积
- USACO Section 5.1 Fencing the Cows - 凸包模板题~~
- android 4.0.4系统下实现apk的静默安装和启动
- 理论知识整理(C语言)
- 解决ultravnc在win2008 R2下CTRL+ALT+DELETEA组合键发送失败的问题
- C语言输出螺旋矩阵
- seajs 2.3.0 傻瓜式入门
- poj 3348 Cows 凸包模板题
- Linux ARM交叉编译器设定
- vs自动生成的WebService配置文件在部署到IIs6后,服务调用失败的解决方法
- 指针
- 查看搜集统计信息的estimate_percent
- 数据结构_二叉树的先序建立与先序,中序,后序(递归)遍历方式_C语言源代码
- 【GoldenGate】使用OGG,两个Oracle库之间单向同步数据
- Cocos2d-x3.1UserDefaule类详解
- POJ 1789 Truck History(最小生成树)