zoukankan      html  css  js  c++  java
  • 【BZOJ2618】[Cqoi2006]凸多边形 半平面交

    【BZOJ2618】[Cqoi2006]凸多边形

    Description

    逆时针给出n个凸多边形的顶点坐标,求它们交的面积。例如n=2时,两个凸多边形如下图:

    则相交部分的面积为5.233。

    Input

    第一行有一个整数n,表示凸多边形的个数,以下依次描述各个多边形。第i个多边形的第一行包含一个整数mi,表示多边形的边数,以下mi行每行两个整数,逆时针给出各个顶点的坐标。

    Output

        输出文件仅包含一个实数,表示相交部分的面积,保留三位小数。

    Sample Input

    2
    6
    -2 0
    -1 -2
    1 -2
    2 0
    1 2
    -1 2
    4
    0 -3
    1 -1
    2 2
    -1 0

    Sample Output

    5.233

    HINT

    100%的数据满足:2<=n<=10,3<=mi<=50,每维坐标为[-1000,1000]内的整数

    题解:半平面交板子题,刷板子~

    注意先弹t后弹h。

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <cmath>
    #include <algorithm>
    using namespace std;
    const int maxn=510;
    const double eps=1e-9;
    struct point
    {
    	double x,y;
    	point() {}
    	point(double a,double b) {x=a,y=b;}
    	point operator + (const point &a) const {return point(x+a.x,y+a.y);}
    	point operator - (const point &a) const {return point(x-a.x,y-a.y);}
    	double operator * (const point &a) const {return x*a.y-y*a.x;}
    	point operator * (const double &a) const {return point(a*x,a*y);}
    }p[maxn];
    int m,n,h,t,np,q[maxn];
    struct line
    {
    	point p,v;
    	double a;
    	line() {}
    	line(point x,point y) {p=x,v=y,a=atan2(v.y,v.x);}
    }l[maxn];
    point getp(line l1,line l2)
    {
    	point u=l1.p-l2.p;
    	double temp=(l2.v*u)/(l1.v*l2.v);
    	return l1.p+l1.v*temp;
    }
    bool onlft(line a,point b)
    {
    	return a.v*(b-a.p)>eps;
    }
    bool cmp(line a,line b)
    {
    	if(fabs(a.a-b.a)<eps)	return onlft(a,b.p);
    	return a.a<b.a;
    }
    void HPI()
    {
    	sort(l+1,l+n+1,cmp);
    	int i,j;
    	for(i=2,j=1;i<=n;i++)	if(fabs(l[i].a-l[j].a)>eps)	l[++j]=l[i];
    	n=j,h=t=q[1]=1;
    	for(i=2;i<=n;i++)
    	{
    		while(h<t&&onlft(l[i],getp(l[q[t]],l[q[t-1]])))	t--;
    		while(h<t&&onlft(l[i],getp(l[q[h]],l[q[h+1]])))	h++;
    		q[++t]=i;
    	}
    	while(h<t&&onlft(l[q[h]],getp(l[q[t]],l[q[t-1]])))	t--;
    	while(h<t&&onlft(l[q[t]],getp(l[q[h]],l[q[h+1]])))	h++;
    	q[++t]=q[h];
    	for(i=h,np=0;i<t;i++)	p[++np]=getp(l[q[i]],l[q[i+1]]);
    }
    double getarea()
    {
    	if(np<3)	return 0;
    	double ret=0;
    	for(int i=2;i<=np;i++)	ret+=p[i-1]*p[i];
    	ret+=p[np]*p[1];
    	return fabs(ret/2);
    }
    inline int rd()
    {
    	int ret=0,f=1;	char gc=getchar();
    	while(gc<'0'||gc>'9')	{if(gc=='-')f=-f;	gc=getchar();}
    	while(gc>='0'&&gc<='9')	ret=ret*10+gc-'0',gc=getchar();
    	return ret*f;
    }
    int main()
    {
    	int i,j,a;
    	m=rd();
    	for(i=1;i<=m;i++)
    	{
    		a=rd();
    		for(j=1;j<=a;j++)	p[j].x=rd(),p[j].y=rd();
    		for(j=1;j<=a;j++)	l[++n]=line(p[j],p[j]-p[j%a+1]);
    	}
    	HPI();
    	printf("%.3lf
    ",getarea());
    	return 0;
    }//8 0 0 0 2 1 2 1 1 2 1 2 2 3 2 3 0
  • 相关阅读:
    《CLR.via.C#第三版》第二部分第6,7章节读书笔记(三)
    《CLR.via.C#第三版》第二部分第4,5章节读书笔记(二)
    《CLR.via.C#第三版》第一部分读书笔记(一)
    https ssl
    bower 代理
    哦?
    Gulp 相关
    Edge浏览器的几个创意应用
    软件中英对照
    Windows 10 Mobile 演示:插入耳机自动执行 APP
  • 原文地址:https://www.cnblogs.com/CQzhangyu/p/7500571.html
Copyright © 2011-2022 走看看