【】 Pipe POJ 1039
Description] [Title has a tube, there are n inflection point, width of the tube 1, can be asked whether or not a straight line passing through this tube, if not, to reach the farthest ask where the abscissa point output shine
[Title] ideas we can think that this light can pass through the tube is the limiting case, the point of touching the bottom surface of a point and a point on the top surface, so we only need to enumerate the following points and the straight line connecting the above, It determines whether it can pass through all the pipes
note:
1 determines whether light passing through the turning point of the current tube, based on this line segment is not the tubes and the upper and lower turning point of the composition is tangential to the point
2. Initially not want to understand, direct enumeration, to make it clear later
1 #include<cstdio> 2 #include<algorithm> 3 #define ll double 4 using namespace std; 5 const int MAXN = 510; 6 const double eps = 1e-3; 7 struct P 8 { 9 ll x, y; 10 P(ll a=0,ll b=0):x(a),y(b){} 11 P operator-(P a) { return P(x - a.x, y - a.y); } 12 P operator+(P a) { return P(x + a.x, y + a.y); } 13 ll operator^(P a) { return a.y*x - a.x*y; } 14 ll operator*(P a) { return a.x*x + a.y*y; } 15 }up[MAXN],down[MAXN]; 16 struct L 17 { 18 P s, t; 19 L() {}; 20 L(P a, P b) :s(a), t(b) {} 21 }up_L[MAXN],down_L[MAXN]; 22 int sgn(double x) 23 { 24 if (x > eps) return 1; 25 if (x < -eps) return -1; 26 return 0; 27 } 28 ll cross(P a, P b) 29 { 30 return a ^ b; 31 } 32 ll cross(P a, P b, P c) 33 { 34 return (a - c) ^ (b - c); 35 } 36 int L_is_inter(L a, L b) 37 { 38 return sgn(cross(b.s, a.s, a.t))*sgn(cross(b.t, a.s, a.t)); 39 } 40 bool S_is_inter(L a, L b) 41 { 42 return sgn((a.s - a.t) ^ (b.s - b.t)) == 0; 43 } 44 P get_inter(L a, L b) 45 { 46 return a.s + (a.t - a.s)*(cross(b.t - b.s, a.s - b.s)) / cross(a.t - a.s, b.t - b.s); 47 } 48 int main() 49 { 50 int n=1; 51 while (1) 52 { 53 scanf("%d", &n);if (n==0) break; 54 for (int i = 1; i <= n; i++) 55 { 56 double x, y; 57 scanf("%lf %lf ", &x, &y); 58 up[i] = P(x, y); 59 down[i] = P(x, y - 1); 60 if (i == 1) continue; 61 up_L[i] = L(up[i - 1], up[i]); 62 down_L[i] = L(down[i - 1], down[i]); 63 } 64 ll ans = -10000000000.0; 65 P tmp; 66 bool flag = 0; 67 for (int i = 1; i <= n; i++) 68 { 69 for (int j = 1; j <= n; j++) 70 { 71 if (i == j) continue; 72 L t = L(down[i], up[j]); 73 int k; 74 for ( k = 1; k <= n; k++) 75 { 76 L line = L(down[k], up[k]); 77 bool ret = (L_is_inter(t, line)<=0); 78 if (k == 1) 79 { 80 if (ret) 81 continue; 82 else 83 { 84 break; 85 } 86 } 87 if (!ret) 88 { 89 line = L(up[k - 1], up[k]); 90 if (L_is_inter(t, line)<0) 91 { 92 tmp = get_inter(t, line); 93 //printf("i==%d j==%d k=%d tmp==%lf\n", i, j, k, tmp.x); 94 ans = max(ans, tmp.x); 95 } 96 line = L(down[k - 1], down[k]); 97 if (L_is_inter(t, line)<0) 98 { 99 100 tmp = get_inter(t, line); 101 //printf("i==%d j==%d k=%d tmp==%lf\n", i, j, k, tmp.x); 102 ans = max(ans, tmp.x); 103 } 104 break; 105 } 106 } 107 if (k > n) { flag = 1; break; } 108 } 109 if (flag) break; 110 } 111 if (flag) { printf("Through all the pipe.\n"); } 112 else 113 printf("%.2f\n", ans); 114 } 115 return 0; 116 }