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;
}

浙公网安备 33010602011771号