Pipe
Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 9493 Accepted: 2877 Descriptionios
The GX Light Pipeline Company started to prepare bent pipes for the new transgalactic light pipeline. During the design phase of the new pipe shape the company ran into the problem of determining how far the light can reach inside each component of the pipe. Note that the material which the pipe is made from is not transparent and not light reflecting.
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.Inputapp
The input file contains several blocks each describing one pipe component. Each block starts with the number of bent points 2 <= n <= 20 on separate line. Each of the next n lines contains a pair of real values xi, yi separated by space. The last block is denoted with n = 0.Outputide
The output file contains lines corresponding to blocks in input file. To each block in the input file there is one line in the output file. Each such line contains either a real value, written with precision of two decimal places, or the message Through all the pipe.. The real value is the desired maximal x-coordinate of the point where the light can reach from the source for corresponding pipe component. If this value equals to xn, then the message Through all the pipe. will appear in the output file.Sample Inputthis
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.55 0Sample Outputspa
4.67 Through all the pipe.Source3d
/************************************************************************* > File Name: poj_1039.cpp > Author: Howe_Young > Mail: 1013410795@qq.com > Created Time: 2015年05月01日 星期五 09時43分46秒 ************************************************************************/ #include <cstdio> #include <iostream> #include <cstring> #include <cmath> #include <cstdlib> #include <algorithm> #define EPS 1e-8 #define INF 1e6 using namespace std; struct point{ double x, y; }; const int maxn = 100; point p[maxn]; int n; int sgn(double x) { if (fabs(x) < EPS) return 0; return x < 0 ? -1 : 1; } double x_multi(point p1, point p2, point p3) { return (p3.x - p1.x) * (p2.y - p1.y) - (p2.x - p1.x) * (p3.y - p1.y); } void get_intersection(point p1, point p2, point p3, point p4, double &x, double &y) { double a1, b1, c1, a2, b2, c2;//求交點過程 a1 = (p2.y - p1.y) * 1.0; b1 = (p1.x - p2.x) * 1.0; c1 = (p2.x * p1.y - p1.x * p2.y) * 1.0; a2 = (p4.y - p3.y) * 1.0; b2 = (p3.x - p4.x) * 1.0; c2 = (p3.y * p4.x - p4.y * p3.x) * 1.0; x = (b1 * c2 - b2 * c1) / (b2 * a1 - b1 * a2); y = (a1 * c2 - c1 * a2) / (a2 * b1 - a1 * b2); } bool check(point p1, point p2, point p3, point p4)//p1p2是否穿過豎着的p3p4,查看這條線是否與每個拐角處上下鏈接的線段都相交,包括端點 { double d1 = x_multi(p1, p2, p3); double d2 = x_multi(p1, p2, p4); return d1 * d2 <= 0; } bool check2(point p1, point p2, point p3, point p4)//同理看p3, p4這兩個點是否在p1p2兩側,端點不算 { double d1 = x_multi(p1, p2, p3); double d2 = x_multi(p1, p2, p4); return d1 * d2 < 0; } point does(point p1)//它的對應的下一個端點 { p1.y--; return p1; } int main() { while (~scanf("%d", &n) && n) { for (int i = 0; i < n; i++) { scanf("%lf %lf", &p[i].x, &p[i].y); } point p0; double ans = p[0].x; for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { if (i == j) continue; if (check(p[i], does(p[j]), p[0], does(p[0])))//若是光線能夠從入口射進來 { for (int k = 1; k < n; k++) { if (!check(p[i], does(p[j]), p[k], does(p[k])))//若是走到k點這個拐點與管壁相交了,找出相交的點來 { if (check2(p[i], does(p[j]), p[k], p[k - 1]))//若是與上壁相交 { get_intersection(p[i], does(p[j]), p[k], p[k - 1], p0.x, p0.y); if (ans < p0.x) ans = p0.x; break; } if (check2(p[i], does(p[j]), does(p[k]), does(p[k - 1])))//若是與下壁相交 { get_intersection(p[i], does(p[j]), does(p[k]), does(p[k - 1]), p0.x, p0.y); if (ans < p0.x) ans = p0.x; break; }//若是都不相交的話,那麼說明是與上一段的端點相交 if (ans < p[k - 1].x) ans = p[k - 1].x; break; } if (k == n - 1)//若是走到最後都沒break,也就是相交,那麼說明能夠經過這個管道,直接讓他等於最後的x座標 { ans = p[n - 1].x; } } } } } if (sgn(ans - p[n - 1].x) == 0) { puts("Through all the pipe."); } else printf("%.2f\n", ans); } return 0; }