x最大存在于一上一下的端点,换句话说就是x最长的线一定经过一个上端点和一个下端点

#include <iostream>
#include <cmath>
#include <cstdio>

using namespace std;

struct Point{
	double x,y;
	Point(double x=0,double y=0):x(x),y(y){
	};
	Point operator-(Point b){return Point(x-b.x,y-b.y);
	}
	double operator^(Point b){return x*b.y-y*b.x;
	}
	Point operator+(Point b){return Point(x+b.x,y+b.y);
	}
};

struct Line{
	Point s,e;
	Line(Point s,Point e):s(s),e(e){
	};
	Line(){
	};
};

struct Seg{
	Point s,e;
	Seg(Point s,Point e):s(s),e(e){
	};
	Seg(){
	};
};

int sgn(double x){
	if(fabs(x)<1e-8) return 0;
	if(x>0) return 1;
	return -1;
}

int lineInterSeg(Line l1,Seg l2){//直线与线段相交 
    if(sgn((l1.s-l1.e)^(l2.s-l2.e))==0){//两直线方向平行
            if(sgn((l1.s-l2.e)^(l1.s-l1.e))==0) return 1; //l2的e点在直线l1上,两直线重合 
            else return 0; //直线与线段平行 ,不相交 
    }else{
        if(sgn((l2.s-l1.e)^(l1.s-l1.e))*sgn((l2.e-l1.e)^(l1.s-l1.e))<=0) return 2;//l2两个端点在直线l1的两侧 ,若严格相交去= 
        else return 0;//否则不相交,线段在直线的一侧 
    } 
      
}//不相交为0,重合为1,相交为2

const int N=30;
int n;
Point point[N<<1];

Point cross(Line a,Line b){//必须确定两个直线是相交的,或者线段 ,本函数不判断相交性 
	Point res=a.s;
	double t=((a.s-b.s)^(b.s-b.e))/((a.s-a.e)^(b.s-b.e));
	res.x+=(a.e.x-a.s.x)*t;
	res.y+=(a.e.y-a.s.y)*t;
	return res;
}

int main(int argc, char** argv) {
	while(scanf("%d",&n)==1&&n){
		double ans=-9999999;
		int flag=0;
		for(int i=0;i<n;i++){
			scanf("%lf%lf",&point[i].x,&point[i].y);
			point[i+n]=point[i]+Point(0,-1);
		}
		for(int i=0;i<n;i++){
			for(int j=n;j<n<<1;j++){
				if(i==j+n) continue;
				int g=0;
				for( g=0;g<n;g++){
					if(g==0){//第一组点为发光处 
						if(lineInterSeg(Line(point[i],point[j]),Seg(point[g],point[g+n]))) continue;//经发光处,跳过下面非第一组时的处理 
						else break;//没经过发光处,不可能的光线,break丢掉 
					}
					if(!lineInterSeg(Line(point[i],point[j]),Seg(point[g],point[g+n]))){//因为是顺序找,所以找到是第一组线段两个都在直线一侧的 ,即直线没穿过线段的点 
						Point cp=cross(Line(point[i],point[j]),Line(point[g],point[g-1]));//直线射到的最远处要么在上线段,要么在下线段
						ans=max(cp.x,ans);		//这里是直线求交点,上下两边都是平行,所以就算比如是这组上边有交点,但下边的延长线与直线的交点一定在上边交点的前面
						cp=cross(Line(point[i],point[j]),Line(point[g+n],point[g+n-1]));//下边求交点 
						ans=max(cp.x,ans);
						break;
					}
				}
				if(g==n) flag=1;//如果直线全部穿过,flag=1 
			}
		}
		if(flag) printf("Through all the pipe.\n");
		else printf("%.2f\n",ans);
	}
	return 0;
}
这里的直线求交点还有一种写法:
Point cross(Line a,Line b){//必须确定两个直线是相交的,或者线段 ,本函数不判断相交性 
	double	a1=a.s.y-a.e.y,	b1=a.e.x-a.s.x,	c1=a.s^a.e,
			a2=b.s.y-b.e.y,	b2=b.e.x-b.s.x,	c2=b.s^b.e,
			d=a1*b2-a2*b1;
	//d如果为0,即sgn(d)==0,则没有交点
	return Point((b1*c2-b2*c1)/d,(a2*c1-a1*c2)/d);
}