Each pipe component consists of many straight pipes connected tightly together. For the programming purposes, the company developed the description of each component as a sequence of points [x1; y1], [x2; y2], . . ., [xn; yn], where x1 < x2 < . . . xn . These are the upper points of the pipe contour. The bottom points of the pipe contour consist of points with y-coordinate decreased by 1. To each upper point [xi; yi] there is a corresponding bottom point [xi; (yi)-1] (see picture above). The company wants to find, for each pipe component, the point with maximal x-coordinate that the light will reach. The light is emitted by a segment source with endpoints [x1; (y1)-1] and [x1; y1] (endpoints are emitting light too). Assume that the light is not bent at the pipe bent points and the bent points do not stop the light beam.
4 0 1 2 2 4 1 6 4 6 0 1 2 -0.6 5 -4.45 7 -5.57 12 -10.8 17 -16.550
枚举一个上顶点,一个下顶点,构成一条直线,如果这条直线可以穿过所有关卡(同样x的上下点构成的直线),说明可以通过,如果没有通过第k个关卡,说明这条直线在k-1到k关卡之间被挡住了,我们判断是挡在了上面还是下面即可。
#include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #include <iostream> #include <vector> #include <queue> #include <set> using namespace std; const double eps = 1e-6; const int maxn = 205+100; const int inf = 0x7fffffff; struct point { double x,y; point() {} point(double _x,double _y) { x = _x; y = _y; } }a[maxn],b[maxn]; struct line { point a; point b; line() {} line(point _s,point _e) { a = _s; b = _e; } }; int n; int dblcmp(double d) { if(fabs(d)<eps) return 0; return d>0?1:-1; } double dis(point t1,point t2) { return sqrt((t1.x-t2.x)*(t1.x-t2.x)+(t1.y-t2.y)*(t1.y-t2.y)); } double x_mul(point p0,point p1,point p2) { return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y); } double cross(line l1,line l2) { double s1 = x_mul(l1.a,l1.b,l2.a); double s2 = x_mul(l1.a,l1.b,l2.b); return (s1*l2.b.x-s2*l2.a.x)/(s1-s2); } bool judge(line l1,line l2) { int x1 = dblcmp(x_mul(l2.a,l1.a,l1.b)); int x2 = dblcmp(x_mul(l2.b,l1.a,l1.b)); if(x1*x2>0) return false; return true; } int main() { while(~scanf("%d",&n)&&n) { int flag = 0; for(int i=0;i<n;i++) { scanf("%lf %lf",&a[i].x,&a[i].y); b[i].x = a[i].x; b[i].y = a[i].y-1.0; } double ans = -inf; for(int i=0;i<n;i++) { for(int j=0;j<n;j++) { int k=0; for(;k<n;k++) { line t1 = line(a[i],b[j]); line t2 = line(a[k],b[k]); if(!judge(t1,t2)) break; } if(k>=n) { flag = 1; break; } else if(k>max(i,j)) { line t1 = line(a[i],b[j]); line t2 = line(b[k-1],b[k]); if(judge(t1,t2)) { ans = max(ans,cross(t1,t2)); //printf("%d %d %d %d %.3f\n",2,k,i,j,ans); } t2 = line(a[k-1],a[k]); if(judge(t1,t2)) { ans = max(ans,cross(t1,t2)); // printf("%d %d %d %d %.3f\n",1,k,i,j,ans); } } } if(flag) break; } if(flag) puts("Through all the pipe."); else printf("%.2f\n",ans); } return 0; }