bzoj2618凸多邊形面積交

http://www.lydsy.com/JudgeOnline/problem.php?id=2618

(⊙v⊙)嗯,幾何大水題


題意是要求n個凸多邊形(逆時針給定點)的面積交,數據很弱。

把每個多邊形拆成直線,然後掃一遍做半平面交,最後統計答案就可以了:


#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<queue>
#include<cmath>
#define eps 1e-10
using namespace std;
const int maxn=505;
int dcmp(double x)
{
	if(fabs(x)<eps)return 0;
	else return x<0?-1:1;
}
struct point
{
	double x,y;
	point(){}
	point(double _x,double _y)
	{
		x=_x;
		y=_y;
	}
	point operator +(const point &b)
	{
		return point(x+b.x,y+b.y);
	}
	point operator -(const point &b)
	{
		return point(x-b.x,y-b.y);
	}
	point operator *(const double &b)
	{
		return point(x*b,y*b);
	}
};
struct line
{
	point p,v;
	double ang;
	line(){}
	line(point _p,point _v)
	{
		p=_p;
		v=_v;
		ang=atan2(v.y,v.x);
	}
	bool operator <(const line &l)const
	{
		return ang<l.ang;
	}
};
double cross(point a,point b)
{
	return a.x*b.y-a.y*b.x;
}
double dot(point a,point b)
{
	return a.x*b.x+a.y*b.y;
}
bool onleft(line l,point p)
{
	return dcmp(cross(l.v,p-l.p))>0;
}
point getsec(point p1,point v1,point p2,point v2)
{
	double x=cross(p2-p1,v2)/cross(v1,v2);
	return v1*x+p1;
}
void hp(line *L,int n)
{
	sort(L+1,L+n+1);
	int first,last;
	point p[maxn];
	line q[maxn];
	q[first=last=0]=L[1];
	for(int i=2;i<=n;i++)
	{
		while(first<last&&!onleft(L[i],p[last-1]))last--;
		while(first<last&&!onleft(L[i],p[first]))first++;
		q[++last]=L[i];
		if(dcmp(cross(q[last].v,q[last-1].v))==0)
		{
			last--;
			if(!onleft(L[i],p[last-1]))q[last]=L[i];
		}
		if(first<last)p[last-1]=getsec(q[last].p,q[last].v,q[last-1].p,q[last-1].v);
	}
	while(first<last&&!onleft(q[first],p[last-1]))last--;
	if(last-first<=1)
	{
		printf("0.000\n");
		return ;
	}
	p[last]=getsec(q[last].p,q[last].v,q[first].p,q[first].v);
	double ans=0;
	for(int i=first;i<last;i++)ans+=cross(p[i]-p[first],p[i+1]-p[first]);
	ans=0.5*fabs(ans);
	printf("%.3f\n",ans);
	
	//for(int i=first;i<=last;i++)printf("%lf  %lf\n",p[i].x,p[i].y);
}
point p[maxn];
line l[maxn];
int cnt;
int main()
{
	int n;
	cnt=0;
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
	{
		int m;
		scanf("%d",&m);
		for(int j=1;j<=m;j++)scanf("%lf%lf",&p[j].x,&p[j].y);				
		p[m+1]=p[1];
		for(int j=1;j<=m;j++)
		{
			l[++cnt]=line(p[j],p[j+1]-p[j]);
		}
	}
	hp(l,cnt);
	return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章