BZOJ 2618: [Cqoi2006]凸多边形
Description
\(n\)个凸多边形求交的面积.
Solution
半平面交模板题.
Code
#include <bits/stdc++.h> using namespace std; namespace CG { typedef double LD; const LD eps = 1e-12; int dcmp(LD x) { return fabs(x)<eps?0:(x>0?1:-1); } struct Point { LD x,y; Point(LD _x=0,LD _y=0) :x(_x),y(_y) {} }; typedef Point Vector; Vector operator + (const Vector &a,const Vector &b) { return Vector(a.x+b.x,a.y+b.y); } Vector operator - (const Vector &a,const Vector &b) { return Vector(a.x-b.x,a.y-b.y); } Vector operator * (const Vector &a,const LD &b) { return Vector(a.x*b,a.y*b); } LD Cross(Vector a,Vector b) { return a.x*b.y-a.y*b.x; } LD get_a(Vector a) { return atan2(a.y,a.x); } struct Line { Point p; Vector v; LD ang; Line(Point _p=Point(),Vector _v=Vector()) :p(_p),v(_v) { ang=get_a(_v); } Point get_p(LD t) { return p+v*t; } int chkl(Point pt) { return Cross(v,pt-p)>0; } }; int cmpa(const Line &a,const Line &b) { return a.ang<b.ang; } Point get_l_l(Line a,Line b) { Vector u=a.p-b.p; LD t=Cross(b.v,u)/Cross(a.v,b.v); return a.get_p(t); } int get_h_h(vector<Line> &ls,vector<Point> &pol) { sort(ls.begin(),ls.end(),cmpa); vector<Line> q(ls.size()); vector<Point> p(ls.size()); int h,t; q[h=t=0]=ls[0]; for(int i=1;i<(int)ls.size();i++) { while(h<t && !ls[i].chkl(p[t-1])) t--; while(h<t && !ls[i].chkl(p[h])) h++; q[++t]=ls[i]; if(dcmp(Cross(q[t].v,q[t-1].v))==0) { t--; if(q[t].chkl(ls[i].p)) q[t]=ls[i]; }if(h<t) p[t-1]=get_l_l(q[t],q[t-1]); } while(h<t && !q[h].chkl(p[t-1])) t--; p[t]=get_l_l(q[h],q[t]); for(int i=h;i<=t;i++) pol.push_back(p[i]); return t-h+1; } LD get_s(vector<Point> &pol) { if(pol.size()<3) return 0; LD S=0; for(int i=2;i<(int)pol.size();i++) S+=fabs(Cross(pol[i-1]-pol[0],pol[i]-pol[0])); return S/2; } }; using namespace CG; const int N = 105; int n,m; Point p[N]; vector<Line> ls; vector<Point> pt; int main() { for(scanf("%d",&n);n--;) { scanf("%d",&m); for(int i=1;i<=m;i++) scanf("%lf%lf",&p[i].x,&p[i].y); for(int i=1;i<m;i++) ls.push_back(Line(p[i],p[i+1]-p[i])); ls.push_back(Line(p[m],p[1]-p[m])); } get_h_h(ls,pt); /* cout<<pt.size()<<endl; for(int i=0;i<(int)pt.size();i++) cout<<pt[i].x<<" "<<pt[i].y<<endl;*/ printf("%.3lf\n",get_s(pt)); return 0; }