Question:
Returns the maximum abscissa of light.
Note that the light may overlap with the pipe
It can also go through the Turning Point
Solution:
Enumerate whether each light can pass the cross section (Line Segment) at each turning point
// Big white p263 # include <cmath> # include <cstdio> # include <cstring> # include <string> # include <queue> # include <functional> # include <set> # include <iostream> # include <vector> # include <algorithm> using namespace std; const double eps = 1e-8; // precision const int INF = 1 <29; const double PI = acos (-1.0); int dcmp (double x) {// judge that double is equal to 0 or... If (fabs (x) <eps) return 0; else return x <0? -1:1;} struct Point {double x, y; Point (double x = 0, double y = 0): x (x), y (y ){}}; typedef Point Vector; typedef vector <Point> Polygon; Vector operator + (Vector a, Vector B) {return Vector (. x + B. x,. y + B. y);} // Vector + Vector = Vector operator-(Point a, Point B) {return Vector (. x-b.x,. y-b.y);} // point-point = Vector operator * (Vector a, double p) {return Vector (. x * p,. y * p);} // Vector * real number = Vector operator/(Vector a, double p) {retur N Vector (. x/p,. y/p);} // vector/real number = vector bool operator <(const Point & A, const Point & B) {return dcmp (. x-B.x) <0 | (dcmp (. x-B.x) = 0 & dcmp (. y-B.y) <0);} bool operator = (const Point & a, const Point & B) {return dcmp (. x-b.x) = 0 & dcmp (. y-b.y) = 0;} bool operator! = (Const Point & a, const Point & B) {return a = B? False: true;} struct Segment {Point a, B; Segment () {} Segment (Point _ a, Point _ B) {a = _ a, B = _ B ;} bool friend operator <(const Segment & p, const Segment & q) {return p. a <q. a | (p. a = q. a & p. B <q. b);} bool friend operator = (const Segment & p, const Segment & q) {return (p. a = q. a & p. B = q. b) | (p. a = q. B & p. B = q. a) ;}}; struct Circle {Point c; double r; Circle () {}circle (Point _ c, double _ r): c (_ c ), r (_ r) {} Point point (do Uble a) const {return Point (c. x + cos (a) * r, c. y + sin (a) * r);} bool friend operator <(const Circle & a, const Circle & B) {return. r <B. r ;}}; struct Line {Point p; Vector v; double ang; Line () {}line (const Point & _ p, const Vector & _ v ): p (_ p), v (_ v) {ang = atan2 (v. y, v. x);} bool operator <(const Line & L) const {return ang <L. ang ;}}; double Dot (Vector a, Vector B) {return. x * B. x +. y * B. y;} // | a | * | B | * cos θ vertex product double Le Ngth (Vector a) {return sqrt (Dot (a, a) ;}// | a | Vector length double Angle (Vector a, Vector B) {return acos (Dot (a, B)/Length (a)/Length (B);} // Vector angle θ double Cross (Vector a, Vector B) {return. x * B. y-a.y * B. x ;}// the area of the parallelogram enclosed by the Cross product vector, double Area2 (Point a, Point B, Point c) {return Cross (B-a, c-);} // double DegreeToRadius (double deg) {return deg/180 * PI;} double GetRerotateAngle (Vector a, Vector B) {// vector a rotates theta clockwise to obtain the side of vector B. To double tempa = Angle (a, Vector (1, 0); if (. y <0) tempa = 2 * PI-tempa; double tempb = Angle (B, Vector (1, 0); if (B. y <0) tempb = 2 * PI-tempb; if (tempa-tempb)> 0) return tempa-tempb; else return tempa-tempb + 2 * PI ;} double torad (double deg) {return deg/180 * PI;} // angular to radian Vector Rotate (Vector a, double rad) {// returns Vector (. x * cos (rad)-. y * sin (rad),. x * sin (rad) +. y * cos (rad);} Vector Normal (Vector a) {// count Returns Vector (-. y/L,. x/L);} Point GetLineProjection (Point p, Point a, Point B) {// projection Vector v = B-a on a straight line; return a + v * (Dot (v, p-a)/Dot (v, v);} Point GetLineIntersection (Point p, Vector v, Point q, Vector w) {// returns the Vector u = p-q; double t = Cross (w, u)/Cross (v, w ); return p + v * t;} int ConvexHull (Point * p, int n, Point * sol) {// calculate the convex hull sort (p, p + n ); int m = 0; for (int I = 0; I <n; I ++ ){ While (m> 1 & Cross (sol [M-1]-sol [m-2], p [I]-sol [m-2]) <= 0) m --; sol [m ++] = p [I];} int k = m; for (int I = n-2; I> = 0; I --) {while (m> k & Cross (sol [M-1]-sol [m-2], p [I]-sol [m-2]) <= 0) m --; sol [m ++] = p [I];} if (n> 0) m --; return m;} double Heron (double a, double B, double c) {// Helen formula double p = (a + B + c)/2; return sqrt (p * (p-a) * (p-B) * (p-c);} bool SegmentProperIntersection (Point a1, Point a2, Point b1, Point b2) {// specifies the intersection of line segments to determine the double C1 = Cross (a2-a1, b1-a1), c2 = Cross (a2-a1, b2-a1); double c3 = Cross (b2-b1, a1-b1), c4 = Cross (b2-b1, a2-b1 ); return dcmp (c1) * dcmp (c2) <0 & dcmp (c3) * dcmp (c4) <0;} double CutConvex (const int n, Point * poly, const Point a, const Point B, vector <Point> result [3]) {// returns a straight line a B cutting a convex polygon vector <Point> points; Point p; point p1 = a, p2 = B; int cur, pre; result [0]. clear (); result [1]. clear (); result [2]. clear (); if (n = 0) return 0; d Ouble tempcross; tempcross = Cross (P2-P1, poly [0]-p1); if (dcmp (tempcross) = 0) pre = cur = 2; else if (tempcross> 0) pre = cur = 0; else pre = cur = 1; for (int I = 0; I <n; I ++) {tempcross = Cross (P2-P1, poly [(I + 1) % n]-p1); if (dcmp (tempcross) = 0) cur = 2; else if (tempcross> 0) cur = 0; else cur = 1; if (cur = pre) {result [cur]. push_back (poly [(I + 1) % n]);} else {p1 = poly [I]; p2 = poly [(I + 1) % n]; p = GetLineIntersection (p1, P2-P1, a, B-a); poin Ts. push_back (p); result [pre]. push_back (p); result [cur]. push_back (p); result [cur]. push_back (poly [(I + 1) % n]); pre = cur ;}} sort (points. begin (), points. end (); if (points. size () <2) {return 0;} else {return Length (points. front ()-points. back () ;}} double DistanceToSegment (Point p, Segment s) {// distance from a Point to a line Segment if (s. a = s. b) return Length (p-s.a); Vector v1 = s. b-s.a, v2 = p-s.a, v3 = p-s. B; if (dcmp (Dot (v1, v2) <0) return L Ength (v2); else if (dcmp (Dot (v1, v3)> 0) return Length (v3); else return fabs (Cross (v1, v2 )) /Length (v1);} bool isPointOnSegment (Point p, Segment s) {return Cross (s. a-p, s. b-p) = 0 & Dot (s. a-p, s. b-p) <0;} int isPointInPolygon (Point p, Point * poly, int n) {// relationship between Point and polygon position int wn = 0; for (int I = 0; I <n; I ++) {Point & p2 = poly [(I + 1) % n]; if (isPointOnSegment (p, segment (poly [I], p2) return-1; // point in the boundary int k = dcmp (Cross (p2-po Ly [I], p-poly [I]); int d1 = dcmp (poly [I]. y-p.y); int d2 = dcmp (p2.y-p. y); if (k> 0 & d1 <= 0 & d2> 0) wn ++; if (k <0 & d2 <= 0 & d1> 0) wn --;} if (wn) return 1; // point in the internal else return 0; // Point externally} double PolygonArea (vector <Point> p) {// polygon directed area double area = 0; int n = p. size (); for (int I = 1; I <n-1; I ++) area + = Cross (p [I]-p [0], p [I + 1]-p [0]); return area/2;} int GetLineCircleIntersection (Line L, Circle C, Point & p1, Point & p2) {// returns the intersection of a circle and a straight line Number of return intersections double a = L. v. x, B = L. p. x-C. c. x, c = L. v. y, d = L. p. y-C.c.y; double e = a * a + c * c, f = 2 * (a * B + c * d), g = B * B + d * d-C. r * C. r; double delta = f * f-4 * e * g; if (dcmp (delta) <0) return 0; // if (dcmp (delta) = 0) {// tangent p1 = p1 = C. point (-f/(2 * e); return 1 ;}// intersection p1 = (L. p + L. v * (-f-sqrt (delta)/(2 * e); p2 = (L. p + L. v * (-f + sqrt (delta)/(2 * e); return 2;} double rotating_calipers (Point * ch, int n) // rotate the card shell {Int q = 1; double ans = 0; ch [n] = ch [0]; for (int p = 0; p <n; p ++) {while (Cross (ch [q + 1]-ch [p + 1], ch [p]-ch [p + 1])> cross (ch [q]-ch [p + 1], ch [p]-ch [p + 1]) q = (q + 1) % n; ans = max (ans, max (Length (ch [p]-ch [q]), length (ch [p + 1]-ch [q + 1]);} return ans;} Polygon CutPolygon (Polygon poly, Point a, Point B) {// use a-> B to cut the Polygon and return the left Polygon newpoly; int n = poly. size (); for (int I = 0; I <n; I ++) {Point c = poly [I]; Point d = poly [(I + 1) % n]; if (dcmp (Cross (B-a, c-a)> = 0) newpoly. push_back (c); if (dcmp (Cross (B-a, c-d ))! = 0) {Point ip = GetLineIntersection (a, B-a, c, d-c); if (isPointOnSegment (ip, Segment (c, d) newpoly. push_back (ip) ;}} return newpoly;} int GetCircleCircleIntersection (Circle c1, Circle c2, Point & p1, Point & p2) {double d = Length (c1.c-c2.c ); if (dcmp (d) = 0) {if (dcmp (c1.r-c2.r) = 0) return-1; // returns 0 when two circles overlap ;} if (dcmp (c1.r + c2.r-d) <0) return 0; if (dcmp (fabs (c1.r-c2.r)-d)> 0) return 0; double a = Angle (c2.c-c1.c, V Ector (); double da = acos (c1.r * c1.r + d * d-c2.r * c2.r)/(2 * c1.r * d )); p1 = c1.point (a-da); p2 = c1.point (a + da); if (p1 = p2) return 1; return 2 ;} // compute // -------------------------------------------- // specify int n; Point arr [25], arr2 [25]; double fuck (Line l) {Point P; int I; for (I = 0; I <n; I ++) {p = GetLineIntersection (l. p, l. v, arr [I], arr2 [I]-arr [I]); if (dcmp (p. y-arr [I]. y)> 0 | dcmp (p. y-arr2 [I]. y) <0) {if (I = 0) return arr [0]. x; Point q = GetLineIntersection (l. p, l. v, arr [I], arr [I]-arr [I-1]); p = GetLineIntersection (l. p, l. v, arr2 [I], arr2 [I]-arr2 [I-1]); return max (p. x, q. x) ;}} return arr [n-1]. x;} int main () {while (scanf ("% d", & n )! = EOF & n) {for (int I = 0; I <n; I ++) {scanf ("% lf", & arr [I]. x, & arr [I]. y); arr2 [I]. x = arr [I]. x; arr2 [I]. y = arr [I]. y-1;} double ans = arr [0]. x; for (int I = 0; I <n; I ++) {for (int j = 0; j <n; j ++) if (I! = J) {Line l1 (arr [I], arr [I]-arr2 [j]); ans = max (ans, fuck (l1 ));}} if (dcmp (ans-arr [n-1]. x) <0) printf ("%. 2lf \ n ", ans); else puts (" Through all the pipe. ");} return 0 ;}