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;
    }
  • 相关阅读:
    JQuery
    C#基础知识
    CSS
    学习.NET
    Grunt常见问题
    一个小型的类库
    SQL字符串处理!
    安装Java8以后,Eclipse运行异常解决方案
    谈薪四式让你谈好薪
    使用js实现input输入框的增加
  • 原文地址:https://www.cnblogs.com/pach/p/7219478.html
Copyright © 2011-2022 走看看