• Uyuw's Concert


    题目链接:http://poj.org/problem?id=2451

    题意:要搭建舞台举行晚会,公园里有很多长椅,每条长椅的位置由一条线段表示,椅子是固定的,搬不动。现在要求所有座位都能看到舞台,求舞台的最大面积是多少。

    思路:先用半平面交求出凸变形,然后再根据差积求面积即可。

    #include<bits/stdc++.h>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<vector>
    #include<map>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    const int maxn=20010;
    const int bound=10000;
    const double esp= 1e-10;
    struct point
    {
        double x,y;
    };
    struct node
    {
        point a,b;
    };
    node pp[maxn];
    int cnt,id[maxn],n;
    double at[maxn];
    int q[maxn*2],front,rear,dg;
    point dpg[maxn];
    void add(double x1,double y1,double x2,double y2)
    {
        pp[cnt].a.x =x1;
        pp[cnt].a .y =y1;
        pp[cnt].b.x =x2;
        pp[cnt++].b.y =y2;
    }
    void read()
    {
        scanf("%d",&n);
        cnt=0;
        double x1,x2,y1,y2;
        for(int i=0; i<n; i++)
        {
            scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
            add(x1,y1,x2,y2);
        }
        n+=4;
        add(0,0,bound,0);
        add(bound,0,bound,bound);
        add(bound,bound,0,bound);
        add(0,bound,0,0);
    }
    int is0(double a)
    {
        if(a<=esp&&a>=-esp)
            return 0;
        if(a>esp)
            return 1;
        return -1;
    }
    double det(double x1,double y1,double x2,double y2)
    {
        return x1*y2-x2*y1;
    }
    
    double ana(point p0,point p1,point p2)
    {
        return det(p1.x-p0.x,p1.y -p0.y,p2.x -p0.x,p2.y -p0.y );
    }
    bool cmp(int a,int b)
    {
        if(at[a]<at[b])
            return true;
        if(is0(at[a]-at[b])==0)
            if(is0(ana(pp[b].a,pp[b].b,pp[a].a ))>=0)
                return true;
        return false;
    }
    void deal()
    {
        for(int i=0; i<n; i++)
        {
            at[i]=atan2(pp[i].b.y-pp[i].a.y,pp[i].b.x -pp[i].a.x );
            id[i]=i;
        }
        sort(id,id+n,cmp);
        int temp=1;
        for(int i=1; i<n; i++)
            if(is0(at[id[i-1]]-at[id[i]])!=0)
                id[temp++]=id[i];
        n=temp;
    }
    point APP(node &t1,node &t2)
    {
        double d1,d2;
        point s1,e1,s2,e2;
        s1=t1.a ;
        e1=t1.b ;
        s2=t2.a ;
        e2=t2.b ;
        point temp;
        d1=ana(s2,e1,s1);
        d2=ana(e1,e2,s1);
        temp.x =(s2.x *d2+e2.x *d1)/(d2+d1);
        temp.y =(s2.y *d2+e2.y *d1)/(d2+d1);
        return temp;
    }
    bool judge(int x,int y,int now)
    {
        point temp=APP(pp[x],pp[y]);
        double d=ana(pp[now].a,pp[now].b,temp);
        if(is0(d)<0)
            return true;
        return false;
    }
    void solve()
    {
        int i;
        front=0;
        rear=1;
        q[0]=id[0];
        q[1]=id[1];
        for(i=2; i<n; i++)
        {
            while(front<rear&&judge(q[rear-1],q[rear],id[i]))
                rear--;
            while(front<rear&&judge(q[front],q[front+1],id[i]))
                front++;
            q[++rear]=id[i];
        }
        while(front<rear&&judge(q[rear-1],q[rear],q[front]))
            rear--;
        while(front<rear&&judge(q[front],q[front+1],q[rear]))
            front++;
        q[++rear]=q[front];
        dg=0;
        for(i=front+1; i<=rear; i++)
            dpg[dg++]=APP(pp[q[i-1]],pp[q[i]]);
    }
    double  area()
    {
        double ans=0;
        for(int i=0; i<dg; i++)
            ans+=dpg[i].x*dpg[(i+1)%dg].y -dpg[(i+1)%dg].x *dpg[i].y ;
        ans=fabs(ans)/2.0;
        return ans;
    }
    int main()
    {
        read();
        deal();
        solve();
        printf("%.1f
    ",area());
        return 0;
    }
  • 相关阅读:
    mac安装sublime text 3,含注册码
    shell脚本--cut命令与awk简单使用
    mac安装VMware虚拟机(含序列号)及Ubuntu系统
    伪静态与重定向--RewriteBase
    伪静态与重定向--RewriteRule
    伪静态与重定向之初体验
    shell脚本--内容查找之grep命令
    shell脚本--文件查找之find命令
    JQuery基础-- Ajax
    安装phpredis扩展
  • 原文地址:https://www.cnblogs.com/zcb123456789/p/13779009.html
Copyright © 2020-2023  润新知