BZOJ2829信用卡凸包
2015-06-02 13:11
645 查看
将每个信用卡内小矩形的四个点加进点集,求凸包,在加上pi*r*r。
证明原理是:凸多边形外角和等于2Pi rad.
模版看起来有点恶心哈哈哈哈。
q1,q2中的点分别是下凸壳和上凸壳。
证明原理是:凸多边形外角和等于2Pi rad.
#include<iostream> #include<cstring> #include<cstdio> #include<algorithm> #include<cstdlib> #include<queue> #include<cmath> #include<vector> using namespace std; #define Vector Point const double pi=3.1415926535898,eps=1e-6; int n,sz=0,cur=0; double a,b,r,l,ans; struct Point{ double x,y; Point(double x=0,double y=0):x(x),y(y){} }p[610000],q1[610000],q2[610000]; void Wa(){ cout<<"Wrong!!!"<<endl; system("pause"); } void in(Point &u){ scanf("%lf%lf",&u.x,&u.y); } double dcmp(double x){ if(abs(x)<eps)return 0; return x; } int Getsign(double x){ if(!dcmp(x))return 0; if(x<0)return -1; return 1; } bool operator <(Point u, Point v){ return u.x<v.x||(v.x==u.x&&u.y<v.y); } bool operator ==(Point u, Point v){ return abs(u.x-v.x)<eps&&abs(u.y-v.y)<eps; } bool operator >(Point u, Point v){ return !(u==v||u<v); } Vector operator -(Point u, Point v){ return Point(u.x-v.x,u.y-v.y); } Vector operator +(Vector u, Vector v){ return Vector(u.x+v.x,u.y+v.y); } double operator *(Vector u, Vector v){ return u.x*v.x+u.y*v.y; } Vector operator *(Vector u, double k){ return Vector(u.x*k, u.y*k); } Vector operator /(Vector u, double k){ if(!k)Wa(); return Vector(u.x/k, u.y/k); } double Cross(Vector u, Vector v){ return u.x*v.y-u.y*v.x; } double AreaTri(Vector u, Vector v){ return Cross(u,v); } Vector Rotate(Vector u, double rad){ return Vector(u.x*cos(rad)-u.y*sin(rad), u.x*sin(rad)+u.y*cos(rad)); } double Length(Vector u){ return sqrt(u.x*u.x+u.y*u.y); } double Angle(Vector u, Vector v){ if(!(Length(u)&&Length(v)))Wa(); return acos(u*v/Length(u)/Length(v)); } Point Getint(Point a, Vector b, Point c, Vector d){ Vector tem=a-c; double t=Cross(d,tem)/Cross(b,d); return a+b*t; } bool Onseg(Point a,Point b,Point c){ return dcmp((a-c)*(b-c))==0&&dcmp(Cross(a-c,b-c))<0; } bool IntLine(Point a, Point b, Point c, Point d) { double c1=Cross(b-a,c-a),c2=Cross(b-a,d-a); double c3=Cross(c-d,a-d),c4=Cross(c-d,b-d); return Getsign(c1)*Getsign(c2)<0 &&Getsign(c3)*Getsign(c4)<0; } bool cmpx(Point u, Point v){ return (v.x-u.x)>eps||(abs(u.x-v.x)<eps&&u.y<v.y); } bool cmp (Point u, Point v){ return u==v; } int main () { scanf("%d%lf%lf%lf",&n,&a,&b,&r); for(int i=1;i<=n;i++){ double x,y,z; scanf("%lf%lf%lf",&x,&y,&z); Vector tem=Vector(x,y); p[++sz]=tem+Rotate(Vector(b/2-r,a/2-r),z); p[++sz]=tem+Rotate(Vector(-b/2+r,a/2-r),z); p[++sz]=tem+Rotate(Vector(b/2-r,-a/2+r),z); p[++sz]=tem+Rotate(Vector(-b/2+r,-a/2+r),z); } sort(p+1,p+1+sz,cmpx); q1[++cur]=p[1],q1[++cur]=p[2]; for(int i=3;i<=sz;i++){ while(cur>1&&Cross(q1[cur]-q1[cur-1],p[i]-q1[cur])<=0)cur--; q1[++cur]=p[i]; } for(int i=1;i<cur;i++)ans+=Length(q1[i+1]-q1[i]); cur=0; q2[++cur]=p[1],q2[++cur]=p[2]; for(int i=3;i<=sz;i++){ while(cur>1&&Cross(q2[cur]-q2[cur-1],p[i]-q2[cur])>=0)cur--; q2[++cur]=p[i]; } for(int i=1;i<cur;i++)ans+=Length(q2[i+1]-q2[i]); printf("%.2f\n",ans+2*r*pi); return 0; }
模版看起来有点恶心哈哈哈哈。
q1,q2中的点分别是下凸壳和上凸壳。
相关文章推荐
- 【Google Code Jam 2009 round2 problem D】Watering Plants (两圆交点求法详解)
- 计算几何模板
- 计算几何小模板
- 凸包问题 hdu1392 Surround the Trees
- HDU 4922 Hello, Your Package! (计算几何+DP)(WA)
- poj 1514&zoj 1185 Metal Cutting(半平面交)
- UVA 10969 Sweet Dream(圆的相交)
- uva 11177 Fighting Against a Polygonal Monster(凸包与圆的面积交)
- POJ1279 && LA2512 Art Gallery(求多边形的核)
- poj 2540 && uva 10084 Hotter Colder(半平面交)
- 【计算几何】POJ 2318 & POJ 2398
- 【计算几何】POJ 2653
- 【计算几何】POJ 1113
- POJ 2318 TOYS(叉积+二分or暴力)
- POJ 2398 Toy Storage(叉积+二分)
- POJ 1228 Grandpa's Estate 计算凸包+判断点在线段上
- POJ 1873 The Fortified Forest 计算凸包
- POJ 2007 Scrambled Polygon 极角排序
- POJ 2074 Line of Sight 直线相交+线段覆盖
- 计算几何问题汇总--圆与矩形