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;
    }
  • 相关阅读:
    Using Resource File on DotNet
    C++/CLI VS CSharp
    JIT VS NGen
    [Tip: disable vc intellisense]VS2008 VC Intelisense issue
    UVa 10891 Game of Sum(经典博弈区间DP)
    UVa 10723 Cyborg Genes(LCS变种)
    UVa 607 Scheduling Lectures(简单DP)
    UVa 10401 Injured Queen Problem(简单DP)
    UVa 10313 Pay the Price(类似数字分解DP)
    UVa 10635 Prince and Princess(LCS N*logN)
  • 原文地址:https://www.cnblogs.com/zufezzt/p/5154825.html
Copyright © 2011-2022 走看看