
之前刷poj计划时刷过,不过也没什么印象了。打铁还是趁热,还没热起来就放弃了,前面算是做了无用功,有如胡乱的看解题报告一样。
题目应该是比较经典的集合入门题,黑书上有一部分核心讲解。
题目中的最优光线必是要经过端点,这个黑书上提到了,应该也可以想到,然后就可以枚举一上一下的端点,判断它最长能走到哪里,首先可以判断出它是否能进的去第i个入口,
这个可以通过叉积进行判断上下点是不是在这条光线异侧,然后求直线的交点。
有一份好的模板很重要~
#include <iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<stdlib.h>
#include<vector>
#include<cmath>
#include<queue>
#include<set>
using namespace std;
#define N 55
#define LL long long
#define INF 0xfffffff
const double eps = 1e-;
const double pi = acos(-1.0);
const double inf = ~0u>>;
struct Point
{
double x,y;
Point(double x=,double y=):x(x),y(y) {} //构造函数 方便代码编写
}p[N];
typedef Point pointt;
pointt operator + (Point a,Point b)
{
return Point(a.x+b.x,a.y+b.y);
}
pointt operator - (Point a,Point b)
{
return Point(a.x-b.x,a.y-b.y);
}
pointt operator * (Point a,double b)
{
return Point(a.x*b,a.y*b);
}
pointt operator / (Point a,double b)
{
return Point(a.x/b,a.y/b);
}
bool operator < (const Point &a,const Point &b)
{
return a.x<b.x||(a.x==b.x&&a.y<b.y);
}
int dcmp(double x)
{
if(fabs(x)<eps) return ;
else return x<?-:;
}
bool operator == (const Point &a,const Point &b)
{
return dcmp(a.x-b.x)==&&dcmp(a.y-b.y)==;
}
//求点积以及利用点积求长度和夹角的函数
double dot(Point a,Point b)
{
return a.x*b.x+a.y*b.y;
}
double cross(Point a,Point b,Point c)//差乘判左右 a->b与a->c向量的关系
{
return (a.x-c.x)*(a.y-b.y)-(a.y-c.y)*(a.x-b.x);
}
bool intersection1(Point p1, Point p2, Point p3, Point p4, Point& p) // 直线相交
{
double a1, b1, c1, a2, b2, c2, d;
a1 = p1.y - p2.y;
b1 = p2.x - p1.x;
c1 = p1.x*p2.y - p2.x*p1.y;
a2 = p3.y - p4.y;
b2 = p4.x - p3.x;
c2 = p3.x*p4.y - p4.x*p3.y;
d = a1*b2 - a2*b1;
if (!dcmp(d)) return false;
p.x = (-c1*b2 + c2*b1) / d;
p.y = (-a1*c2 + a2*c1) / d;
return true;
}
int main()
{
int n,i,j,g;
while(scanf("%d",&n)&&n)
{
for(i = ; i <= n ; i++)
{
scanf("%lf%lf",&p[i].x,&p[i].y);
p[i+n].x = p[i].x;
p[i+n].y = p[i].y-1.0;
}
double ans = -INF;
int flag = ;
for(i = ; i <= n; i++)
{
for(j = n+ ; j <= *n ; j++)
{
if(j==n+i) continue;
Point sg ;
for(g = ; g <= n ; g++)
{
int d1 = dcmp(cross(p[i],p[j],p[g]));
int d2 = dcmp(cross(p[i],p[j],p[g+n]));
if(g==&&d1*d2<=) continue;
if(g==&&d1*d2>) break;
if(d1*d2>)
{
if(intersection1(p[i],p[j],p[g-],p[g],sg))
{
ans = max(ans,sg.x);
}
if(intersection1(p[i],p[j],p[n+g-],p[n+g],sg))
{
ans = max(ans,sg.x);
}
break;
}
}
if(g>n)
{
flag = ;
break;
}
}
if(flag) break;
}
if(flag) puts("Through all the pipe.");
else printf("%.2f\n",ans);
}
return ;
}