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\n",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.\n");
        else printf("%.2lf\n",ans+eps);
    }
    return 0;
}

 

posted @ 2016-01-24 11:01  Fighting_Heart  阅读(198)  评论(0编辑  收藏  举报