• POJ2074:Line of Sight——题解


    http://poj.org/problem?id=2074

    题目大意:(下面的线段都与x轴平行)给两条线段,一个点在其中一条线段看另一条线段,但是中间有很多线段阻挡视线。求在线段上最大连续区间使得在上面的点都能看见另一条线段。

    ——————————————

    这题的思路很简单,首先根据左端点先排个序,然后找前一条线段的右端点和房子左端点连,后一条线段的左端点和房子右端点连,那么两条连线与路的交的范围即是可行解。

    但是debug真的累……好在poj有神犇提供了部分debug数据,经过多次尝试,发现:

    1.筛除不在路和房子之间的线段。

    2.可行解区域可能超过路。

    3.线段可能互相遮挡。

    第三条蛮麻烦的,一个简单粗暴的比较方法就是枚举所有线段,判断是否有和线段相交,如果相交则更换为该线段的左/右端点。

    #include<cstdio>
    #include<queue>
    #include<cctype>
    #include<cstring>
    #include<vector>
    #include<cmath>
    #include<algorithm>
    using namespace std;
    typedef double dl;
    const int INF=2147483647;
    const int N=201;
    struct point{//既是向量又是点
        dl x;
        dl y;
    };
    struct line{
        dl x1;
        dl x2;
        dl y;
    }p[N],st,ed;
    bool cmp(line a,line b){
        return (a.x1<b.x1||(a.x1==b.x1&&a.x2<b.x2)||(a.x1==b.x1&&a.x2==b.x2&&a.y<b.y));
    }
    inline point getmag(point a,point b){
        point s;
        s.x=b.x-a.x;s.y=b.y-a.y;
        return s;
    }
    inline int multiX(point a,point b){
        return a.x*b.y-b.x*a.y;
    }
    inline bool check(point a,point b,point c,point d){
        dl d1=multiX(getmag(c,d),getmag(c,a))*multiX(getmag(c,d),getmag(c,b));
        dl d2=multiX(getmag(a,b),getmag(a,c))*multiX(getmag(a,b),getmag(a,d));
        if(d1<=0&&d2<=0)return 1;
        return 0;
    }
    inline point intersection(point a,point b,point c,point d){
        point s;
        dl a1=a.y-b.y,b1=b.x-a.x,c1=a.x*b.y-b.x*a.y;  
        dl a2=c.y-d.y,b2=d.x-c.x,c2=c.x*d.y-d.x*c.y;  
        s.x=(c1*b2-c2*b1)/(a2*b1-a1*b2);
        s.y=(a2*c1-a1*c2)/(a1*b2-a2*b1);
        return s;
    }
    int n;
    int main(){
        while(scanf("%lf%lf%lf",&st.x1,&st.x2,&st.y)!=EOF&&st.x1+st.x2+st.y!=0){
        scanf("%lf%lf%lf",&ed.x1,&ed.x2,&ed.y);
        scanf("%d",&n);
        for(int i=1;i<=n;i++)scanf("%lf%lf%lf",&p[i].x1,&p[i].x2,&p[i].y);
        sort(p+1,p+n+1,cmp);
        double maxn=0,l=0,r=0;
        bool f=0;
        for(int i=n;i>=1;i--){
            if(p[i].y>st.y||p[i].y<ed.y)continue;
            n=i;
            break;
        }
        for(int i=1;i<=n+1;i++){
            if(p[i].y>st.y||p[i].y<ed.y)continue;
            if(!f){
            l=ed.x1;
            f=1;
            }
            else{
            point a,b,c,d;
            a.x=ed.x1;a.y=ed.y;
            b.x=ed.x2;b.y=ed.y;
            c.x=st.x1;c.y=st.y;
            d.x=p[i-1].x2;d.y=p[i-1].y;
            for(int j=1;j<=n;j++){
                if(p[j].y>st.y||p[j].y<ed.y)continue;
                if(i-1==j)continue;
                point e,f;
                e.x=p[j].x1;e.y=p[j].y;
                f.x=p[j].x2;f.y=p[j].y;
                if(check(c,d,e,f)){
                d=f;
                }
            }
            l=intersection(a,b,c,d).x;
            }
            if(i==n+1)r=ed.x2;
            else{
            point a,b,c,d;
            a.x=ed.x1;a.y=ed.y;
            b.x=ed.x2;b.y=ed.y;
            c.x=st.x2;c.y=st.y;
            d.x=p[i].x1;d.y=p[i].y;
            for(int j=1;j<=n;j++){
                if(p[j].y>st.y||p[j].y<ed.y)continue;
                if(i-1==j)continue;
                point e,f;
                e.x=p[j].x1;e.y=p[j].y;
                f.x=p[j].x2;f.y=p[j].y;
                if(check(c,d,e,f)){
                d=e;
                }
            }
            r=intersection(a,b,c,d).x;
            }
            if(l<r){
            if(l<ed.x1)l=ed.x1;
            if(r>ed.x2)r=ed.x2;
            maxn=max(maxn,r-l);
            }
        }
        if(maxn==0){
            puts("No View");
        }else{
            printf("%.2f
    ",maxn);
        }
        }
        return 0;
    }
  • 相关阅读:
    多条件查询测试用例设计方法(1)—Pairwise(转)
    单例饿汉式和饱汉式各自的有缺点(转)
    Intellij IDEA生成JavaDoc(转)
    Linux常用命令分类
    Linux 常用命令
    数据库简单测试
    postman参数为Json数据结构
    WEB测试常见BUG
    APP应用测试技巧
    APP软件半成品测试技巧
  • 原文地址:https://www.cnblogs.com/luyouqi233/p/8067595.html
Copyright © 2020-2023  润新知