AmazingCounters.com

[POJ]2451: Uyuw's Concert

题目大意:一个10000*10000的舞台,N条有向线,线左边才能布置舞台,求最后舞台面积。(N<=20000)

思路:半平面交模板。

#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
#define MN 20000
#define eps 1e-7
struct point{double x,y;point(double x=0,double y=0):x(x),y(y){}}p[MN+5];
point operator+(point a,point b){return point(a.x+b.x,a.y+b.y);}
point operator-(point a,point b){return point(a.x-b.x,a.y-b.y);}
point operator*(point a,double x){return point(a.x*x,a.y*x);}
double operator*(point a,point b){return a.x*b.y-a.y*b.x;}
struct line{point p,v;line(double a=0,double b=0,double c=0,double d=0):p(a,b),v(c,d){}}l[MN+5];
bool cmp(line a,line b){return atan2(a.v.y,a.v.x)<atan2(b.v.y,b.v.x);}
bool left(line l,point p){return l.v*(p-l.p)<0;}
point xp(line a,line b){return a.p+a.v*(b.v*(a.p-b.p)/(a.v*b.v));}
int q[MN+5],ql,qr;
int main()
{
    int n,i;double ans=0;
    scanf("%d",&n);
    for(i=0;i<n;++i)
        scanf("%lf%lf%lf%lf",&l[i].p.x,&l[i].p.y,&l[i].v.x,&l[i].v.y),
        l[i].v.x-=l[i].p.x,l[i].v.y-=l[i].p.y;
    l[n++]=line(0,0,10000,0);
    l[n++]=line(10000,0,0,10000);
    l[n++]=line(10000,10000,-10000,0);
    l[n++]=line(0,10000,0,-10000);
    sort(l,l+n,cmp);
    for(i=1;i<n;++i)
    {
        while(ql<qr&&left(l[i],p[qr-1]))--qr;
        while(ql<qr&&left(l[i],p[ql]))++ql;
        if(q[++qr]=i,fabs(l[q[qr-1]].v*l[i].v)<eps)
            if(left(l[i],l[q[--qr]].p))q[qr]=i;
        if(ql<qr)p[qr-1]=xp(l[q[qr]],l[q[qr-1]]);
    }
    while(ql<qr&&left(l[q[ql]],p[qr-1]))--qr;
    p[qr]=xp(l[q[qr]],l[q[ql]]);
    for(i=ql;++i<qr;)ans+=(p[i]-p[ql])*(p[i+1]-p[ql]);
    printf("%.1f",ans/2);
}

 

posted on 2017-03-15 15:18  ditoly  阅读(191)  评论(0编辑  收藏  举报