这题的题意是一个通光的管道,假设这种材质不反射光,求从入口任意方向进入的光所能达到的最大的横坐标大小,如果有光能够完全通过管道则输出Through all the pipe.否则输出最大的横坐标值,可以证明的是,最长距离的光一定是经过某两个顶点的,假设有有一条光线不经过顶点,那么通过平移,旋转到顶点上之后所能得到的值一定比原来的要大,所以可以枚举每两个顶点的直线,从左到右依次判断是否在拐点的内部,如果不在说明和前一个拐点所购成了两个线段之间有一条是相交的,那么交点就是最大值
View Code
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#define N 21
#define eps 1e-5
#define left -10e8
using namespace std;
struct point
{
double x,y;
};
point up[N],down[N];
int n;
double getx(point p1,point p2,point p3,point p4)//找到直线和线段相交的横坐标
{
double k1=(p2.y-p1.y)/(p2.x-p1.x);
double k2=(p4.y-p3.y)/(p4.x-p3.x);
double b1=p2.y-k1*p2.x;
double b2=p3.y-k2*p3.x;
return (b2-b1)/(k1-k2);
}
double getans()
{
int i,j,k;
double ans=left,right;
double tx,ty;
point ql,qr,pl,pr;
for(i=0;i<n;i++)
for(j=0;j<n;j++)
{
if(i==j)
continue;
ql=up[i];
qr=down[j];
right=left;
for(k=0;k<n;k++)
{
tx=up[k].x;
ty=(tx-ql.x)*(qr.y-ql.y)/(qr.x-ql.x)+ql.y;
if(ty>down[k].y&&ty<up[k].y||fabs(ty-down[k].y)<eps||fabs(ty-up[k].y)<eps)
right=tx;
else
{
if(k)
{
if(ty<down[k].y)
right=getx(ql,qr,down[k-1],down[k]);
else
right=getx(ql,qr,up[k-1],up[k]);
}
break;
}
}
if(right>ans)
ans=right;
}
return ans;
}
int main()
{
int i,j,k;
while(scanf("%d",&n)&&n)
{
for(i=0;i<n;i++)
{
scanf("%lf%lf",&up[i].x,&up[i].y);
down[i]=up[i];
down[i].y-=1.0;
}
double ans=getans();
if(ans>up[n-1].x||fabs(ans-up[n-1].x)<eps)
printf("Through all the pipe.\n");
else
printf("%.2lf\n",ans);
}
return 0;
}