zoukankan      html  css  js  c++  java
  • POJ 1039 直线和线段相交

    题意:

    题意很好理解,从左边射过来的光线,最远能经过管道到右边多少距离。

    分析:

    光线一定经过一个上端点和一个下端点,这一点很容易想到。然后枚举上下端点即可

    #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 cross_x(Point p1,Point p2,Point p3,Point p4)
    {
        double k1=(p1.y-p2.y)/(p1.x-p2.x);
        double k2=(p3.y-p4.y)/(p3.x-p4.x);
        return (k1*p1.x-k2*p3.x-p1.y+p3.y)/(k1-k2);
    }
    
    double get_y(Point p,Point q,double x)
    {
        return (p.y-q.y)/(p.x-q.x)*(x-p.x)+p.y;
    }
    
    //判断直线和线段相交
    bool Seg_inter_line(Line l1,Line l2) //判断直线l1和线段l2是否相交,<0是把交于线段端点处看做不相交
    {
        return sgn(crs_prdct(l2.p-l1.q,l1.p-l1.q))*sgn(crs_prdct(l2.q-l1.q,l1.p-l1.q)) < 0;
    }
    
    const int maxn=30;
    Point Up[maxn],Dw[maxn];
    
    int main()
    {
    //    freopen("in.txt","r",stdin);
        int n;
        while(scanf("%d",&n),n)
        {
            double x,y;
            for(int i=0; i<n; i++)
            {
                scanf("%lf%lf",&x,&y);
                Up[i]=Point(x,y);
                Dw[i]=Point(x,y-1);
            }
            double ans=Up[0].x;
            for(int i=0; i<n; i++)
            {
                for(int j=0; j<n; j++)
                {
                    if(i==j) continue;
                    for(int k=0; k<n-1; k++)
                    {
                        if(Seg_inter_line(Line(Up[i],Dw[j]),Line(Up[k],Up[k+1])))
                        {
                            ans=max(ans,cross_x(Up[i],Dw[j],Up[k],Up[k+1]));
                            break;
                        }
                        if(Seg_inter_line(Line(Up[i],Dw[j]),Line(Dw[k],Dw[k+1])))
                        {
                            ans=max(ans,cross_x(Up[i],Dw[j],Dw[k],Dw[k+1]));
                            break;
                        }
                        double t=get_y(Up[i],Dw[j],(Up[k].x+Up[k+1].x)/2);
                        if(t>(Up[k].y+Up[k+1].y)/2 || t<(Dw[k].y+Dw[k+1].y)/2)
                        {
                            ans=max(ans,Up[k].x);
                            break;
                        }
                        if(k==n-2) ans=Up[n-1].x;
                    }
                }
            }
            if(sgn(ans-Up[n-1].x)==0) printf("Through all the pipe.
    ");
            else printf("%.2f
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    面向对象的相关知识
    模块的导入
    正怎表达式在爬虫里的应用
    前端~css
    CSS知识点
    初识Html
    Python之路--协程/IO多路复用
    进程
    锁 和 线程池
    操作系统-并发-线程-进程
  • 原文地址:https://www.cnblogs.com/pach/p/7220294.html
Copyright © 2011-2022 走看看