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

  

posted @ 2017-04-17 09:45  北北北北屿  阅读(113)  评论(0编辑  收藏  举报