zoukankan      html  css  js  c++  java
  • POJ 2074 Line of Sight 计算几何

    题意:

    给出房子,障碍物,观光线(都为平行于x轴的线段)。问在观光线上能看到整个房子的最长距离

    分析:

    将房屋的端点与障碍物的端点连线,求出与观光线的横坐标。这些坐标会把观光线分成多个区间,然后枚举每一个区间的中点,来判断这个区间是否能看到整个房子

    要注意的是:不一定每个障碍物都在房屋与观光线之间,与房屋或观光线在同一条直线的可以忽略掉

    如果你用的G++,double输出格式为%f

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    #define eps 1e-8
    #define INF 1e9
    #define OK sgn(tmp-lx1)>0 && sgn(tmp-lx2<0)
    using namespace std;
    
    typedef struct Point
    {
        double x,y;
        Point() {};
        Point(double xx,double yy)
        {
            x=xx;
            y=yy;
        }
    } Vector;
    
    struct Line
    {
        Point p,q;
        Line() {};
        Line(Point pp,Point qq)
        {
            p=pp;
            q=qq;
        }
    };
    
    int sgn(double x)
    {
        if(fabs(x)<eps) return 0;
        return x<0? -1:1;
    }
    
    double crs_prdct(Vector a,Vector b)
    {
        return a.x*b.y-b.x*a.y;
    }
    
    Vector operator - (Point a,Point b)
    {
        return Vector(a.x-b.x,a.y-b.y);
    }
    
    double calcu(Point a,Point b,double y)
    {
        return (a.x-b.x)/(a.y-b.y)*(y-a.y)+a.x;
    }
    
    const int maxn=105;
    Line hou,pro,obs[maxn];
    double dot[maxn];
    
    int main()
    {
    //    freopen("in.txt","r",stdin);
        int n,m;
        double x1,x2,y,lx1,lx2,ly;
        while(scanf("%lf%lf%lf",&x1,&x2,&y))
        {
            if(x1==0 && x2==0 && y==0) break;
            hou=Line(Point(x1,y),Point(x2,y));
            scanf("%lf%lf%lf",&lx1,&lx2,&ly);
            scanf("%d",&n);
            m=0;
            for(int i=0; i<n; i++)
            {
                scanf("%lf%lf%lf",&x1,&x2,&y);
                if(sgn(y-hou.p.y)>=0 || sgn(y-ly)<=0) continue;
                obs[m++]=Line(Point(x1,y),Point(x2,y));
            }
            int cnt=0;
            dot[cnt++]=lx1;
            double tmp;
            for(int i=0; i<m; i++)
            {
                if(obs[i].p.y>=hou.p.y || obs[i].p.y<ly) continue;
                tmp=calcu(hou.p,obs[i].p,ly);
                if(OK) dot[cnt++]=tmp;
                tmp=calcu(hou.p,obs[i].q,ly);
                if(OK) dot[cnt++]=tmp;
                tmp=calcu(hou.q,obs[i].p,ly);
                if(OK) dot[cnt++]=tmp;
                tmp=calcu(hou.q,obs[i].q,ly);
                if(OK) dot[cnt++]=tmp;
            }
            dot[cnt++]=lx2;
            sort(dot,dot+cnt);
            double ans=0;
            tmp=0;
            for(int i=0; i<cnt-1; i++)
            {
                bool flag=true;
                Point mid=Point((dot[i]+dot[i+1])/2,ly);
                for(int j=0; j<m; j++)
                {
                    if(sgn(crs_prdct(hou.p-mid,obs[j].q-mid))<=0 && sgn(crs_prdct(hou.q-mid,obs[j].p-mid))>=0)
                    {
                        flag=false;
                        break;
                    }
                }
                if(flag)
                {
                    tmp+=dot[i+1]-dot[i];
                    ans=max(ans,tmp);
                }
                else tmp=0;
            }
            if(sgn(ans)>0) printf("%.2f
    ",ans);
            else puts("No View");
        }
        return 0;
    }
  • 相关阅读:
    leetcode108 Convert Sorted Array to Binary Search Tree
    leetcode98 Validate Binary Search Tree
    leetcode103 Binary Tree Zigzag Level Order Traversal
    leetcode116 Populating Next Right Pointers in Each Node
    Python全栈之路Day15
    Python全栈之路Day11
    集群监控
    Python全栈之路Day10
    自动部署反向代理、web、nfs
    5.Scss的插值
  • 原文地址:https://www.cnblogs.com/pach/p/7219478.html
Copyright © 2011-2022 走看看