The problem of calculating geometry is very few and far between.
Before WA thought it was the accuracy of the problem, later found that the situation did not consider the whole ... Topic Links:
http://acm.hdu.edu.cn/showproblem.php?pid=5572 Test Instructions:
Given the starting point A and direction V, the path encountered in the cylinder is refracted, asking whether it can reach the end of B. Analysis:
The path is represented as a+t∗v A + t * V to get a two-tuple equation set for T-T and to find out the Δ\delta.
Δ\delta is less than or equal to 0 o'clock, indicating that no refraction occurs. Directly determine if AB is collinear.
Δ\delta is greater than 0 o'clock, find out the root. Root less than 0 indicates that no refraction occurs on the road and that AB is collinear. Root is greater than or equal to 0, still want to determine whether AB collinear, and note that at this point B should be a with the intersection of the line segment. If B is not on the segment, then the refraction can be passed through B. Code:
#include <cstdio> #include <iostream> #include <cstring> #include <algorithm> #include <
Cmath> using namespace std;
typedef long Long LL;
const double eps= 1e-8;
Const double INF = 1E20;
Double Add (double A, double b) {if (Fabs (A + B) < EPS * (Fabs (a) + fabs (b))) return 0;
else return a + B;
} struct point{double x, y; Point () {}-point (Double x, double y): X (x), Y (y) {}-operator + (point P) {return-point (Add (x, p.x), add
(Y, p.y));
} Point operator – (point P) {return point (Add (x,-p.x), add (y,-p.y));
} double dot (point P) {return Add (x * p.y,-y * p.x);
} Point operator * (double D) {return point (x * d, y * d);
}
};
struct circle{point O;
Double R;
Circle () {} circle (double x, double y, double R): O (x, y), R (r) {}};
Point A, B, V;
Circle C; inline int dcmp (double a) {if (Fabs (a) < EPS) return 0; return a < 0? -1:1;} inline bool Online (point A, poinT V, point B) {return dcmp (V.dot (b-a)) = = 0;} inline double GetPos (point A, point B) {if (dcmp (a.x) = = 0) return B.Y/
A.Y;
else return b.x/a.x;
} bool Judge (point A, point V, Circle C, point B) {double AA = v.x * v.x + v.y * V.Y;
Double BB = 2 * v.y * (A.Y-C.O.Y) + 2 * v.x * (a.x-c.o.x);
Double cc = (a.x-c.o.x) * (a.x-c.o.x) + (A.Y-C.O.Y) * (A.Y-C.O.Y)-C.R * C.R;
Double Delta = bb * bb-4 * AA * CC;
Double T1, T2, T;
if (dcmp (delta) <= 0) {if (online (A, V, b)) {t = GetPos (V, b-a);
if (dcmp (t) >= 0) return true;
}} Double anst = INF;
T1 = (-BB + sqrt (delta))/(2 * aa);
T2 = (-bb-sqrt (Delta))/(2 * aa);
if (dcmp (t1) >= 0) {if (dcmp (T2) >= 0) anst = T2;
else anst = T1;
if (online (A, V, b)) {Double T = GetPos (V, b-a);
if (dcmp (t) >= 0 && T <= anst) return true;
} Point tmp = a + v * anst; Point temp = c.o-tmp;
Point revers = Point (-temp.y, temp.x);
Double k = Temp.dot (tmp-b)/Revers.dot (temp);
Point TT = tmp + revers * k;
b = TT * 2-B;
if (online (A, V, b)) {Double tmp = GetPos (V, b-a);
if (DCMP (TMP) >= 0) return true;
}} if (Online (A, V, b)) {Double T = GetPos (V, b-a);
if (dcmp (t) >= 0) return true;
} return false;
} int main (void) {int t;cin>>t;
int cnt = 1;
while (t--) {double QX, QY, R;
cin>>qx>>qy>>r;
c = Circle (QX, QY, R);
Double AX, AY, VX, VY, BX, by;
cin>>ax>>ay>>vx>>vy>>bx>>by;
A = Point (AX, AY);
v = Point (VX, VY);
b = Point (BX, by);
cout<< "Case #" <<cnt<< ":";
if (judge (A, V, C, b)) cout<< "Yes" <<endl;
else cout<< "No" <<endl;
cnt++; } return 0; }