zoukankan      html  css  js  c++  java
  • POJ 1039 Pipe

    枚举两个点作为光线,计算最远的点即可

    可以把管子一段一段分开来看,计算光线是否在每一段管子内,某一段内出界了,那么算交点坐标

    注意判断光线不能进入第一个管子

    #include<cstdio>
    #include<cstring>
    #include<vector>
    #include<cmath>
    #include<queue>
    #include<list>
    #include<algorithm>
    using namespace std;
    
    const double eps=1e-8;
    int n;
    struct Point
    {
        double x;
        double y;
    } point[100];
    struct Line
    {
        Point a;
        Point b;
    }line[100];
    struct X
    {
        double a,b,c;
    }line1,line2;
    struct Pipe
    {
        Line line1;//上面线段
        Line line2;//下面线段
        double leftX;
        double rightX;
        double lineLeftY;
        double lineRightY;
    
    } pipe[100];
    
    Point jiaodian(double a,double b,double c,double d,double e,double f,double g,double h)
    {
        double X1=a,Y1=b,X2=c,Y2=d,X3=e,Y3=f,X4=g,Y4=h;
    
        line1.a=Y2-Y1;
        line1.b=X1-X2;
        line1.c=X2*Y1-X1*Y2;
    
        line2.a=Y4-Y3;
        line2.b=X3-X4;
        line2.c=X4*Y3-X3*Y4;
    
        double ansX=1.0*(line1.b*line2.c-line2.b*line1.c)/(line1.a*line2.b-line2.a*line1.b);
        double ansY=-1.0*(line2.a*line1.c-line1.a*line2.c)/(line1.a*line2.b-line2.a*line1.b);
    
        Point ret;
        ret.x=ansX;
        ret.y=ansY;
    //    printf("--- %.2lf %.2lf
    ",ansX,ansY);
        return ret;
    }
    
    int main()
    {
        while(~scanf("%d",&n))
        {
            if(!n) break;
            for(int i=1; i<=n; i++)
            {
                scanf("%lf%lf",&point[i].x,&point[i].y);
                point[i+n].x=point[i].x;
                point[i+n].y=point[i].y-1;
            }
    
            for(int i=1;i<=n-1;i++)
            {
                line[i].a=point[i];
                line[i].b=point[i+1];
                line[i+n].a=point[i+n];
                line[i+n].b=point[i+n+1];
    
                pipe[i].line1=line[i];
                pipe[i].line2=line[i+n];
            }
    
            for(int i=1;i<=n-1;i++)
            {
                pipe[i].leftX=pipe[i].line1.a.x;
                pipe[i].rightX=pipe[i].line1.b.x;
            }
    
            bool Max=0;
            double ans=-9999999;
            for(int i=1;i<=2*n;i++)
            {
                for(int j=1;j<=2*n;j++)
                {
                    if(fabs(point[i].x-point[j].x)<=eps) continue;
                    double X1=point[i].x;
                    double Y1=point[i].y;
                    double X2=point[j].x;
                    double Y2=point[j].y;
    
                    double A = Y2 - Y1;
                    double B = X1 - X2;
                    double C = X2*Y1 - X1*Y2;
    
                    for(int k=1;k<=n-1;k++)
                    {
                        pipe[k].lineLeftY=(-A*pipe[k].leftX-C)/B;
                        pipe[k].lineRightY=(-A*pipe[k].rightX-C)/B;
                    }
    
                    bool fail=0;
                    for(int k=1;k<=n-1;k++)
                    {
                        if(pipe[k].lineLeftY+eps>=pipe[k].line2.a.y&&pipe[k].lineLeftY<=pipe[k].line1.a.y+eps
                           &&pipe[k].lineRightY+eps>=pipe[k].line2.b.y&&pipe[k].lineRightY<=pipe[k].line1.b.y+eps) continue;
    
                        else
                        {
                            fail=1;
                            if(pipe[k].lineRightY<pipe[k].line2.b.y&&
                               pipe[k].lineLeftY+eps>=pipe[k].line2.a.y&&pipe[k].lineLeftY<=pipe[k].line1.a.y+eps)//和下面的相交了
                            {
                                Point jiaodian1=jiaodian(point[i].x,point[i].y,point[j].x,point[j].y,
                                                         pipe[k].line2.a.x,pipe[k].line2.a.y,pipe[k].line2.b.x,pipe[k].line2.b.y);
                                ans=max(ans,jiaodian1.x);
                            }
                            else if(pipe[k].lineRightY>pipe[k].line1.b.y
                                    &&pipe[k].lineLeftY+eps>=pipe[k].line2.a.y&&pipe[k].lineLeftY<=pipe[k].line1.a.y+eps)//和上面的相交了
                            {
                                Point jiaodian1=jiaodian(point[i].x,point[i].y,point[j].x,point[j].y,
                                                         pipe[k].line1.a.x,pipe[k].line1.a.y,pipe[k].line1.b.x,pipe[k].line1.b.y);
                                ans=max(ans,jiaodian1.x);
                            }
                            break;
                        }
                    }
                    if(fail==0) {Max=1; break;}
                }
                if(Max) break;
            }
            if(Max) printf("Through all the pipe.
    ");
            else printf("%.2lf
    ",ans+eps);
        }
        return 0;
    }
  • 相关阅读:
    ::before和::after伪元素的用法
    JS中map、some、every、filter方法
    C++多线程,互斥,同步
    RAII
    Proxy 代理
    Decorator 装饰
    TCP和UDP的9个区别是什么
    谈谈自己对面向对象的理解
    C++11多线程
    std::move
  • 原文地址:https://www.cnblogs.com/zufezzt/p/5154825.html
Copyright © 2011-2022 走看看