1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70
| #include <cmath> #include <cctype> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm>
using namespace std;
static const long double EPS = 1e-10; int cmp(long double t) { return fabs(t) < EPS ? 0 : t > 0 ? 1 : -1; }
struct Point { long double x, y, z; Point(long double _x = 0, long double _y = 0, long double _z = 0) : x(_x), y(_y), z(_z) {} Point operator + (const Point &a) const { return Point(x + a.x, y + a.y, z + a.z); } Point operator - (const Point &a) const { return Point(x - a.x, y - a.y, z - a.z); } Point operator * (const long double &a) const { return Point(x * a, y * a, z * a); } Point operator / (const long double &a) const { return Point(x / a, y / a, z / a); } Point operator * (const Point &a) const { return Point(y * a.z - z * a.y, z * a.x - x * a.z, x * a.y - y * a.x); } long double operator & (const Point &a) const { return x * a.x + y * a.y + z * a.z; } long double operator ! () const { return sqrt(x * x + y * y + z * z); } long double operator ^ (const Point &a) const { return (*this & a) / (! *this * ! a); } };
struct Line { Point a, b; Line(Point _a = Point(), Point _b = Point()) : a(_a), b(_b) {} long double operator % (const Point &p) const { return ! ((b - a) * (p - a)) / ! (b - a); } };
struct Ball { Point p; long double r; };
struct Solver { private: static const int N = 50; int n; Point a, b; Ball ball[N]; void input() { cin >> n; for (int i = 0; i < n; ++ i) cin >> ball[i].p.x >> ball[i].p.y >> ball[i].p.z >> ball[i].r; cin >> a.x >> a.y >> a.z >> b.x >> b.y >> b.z; } void process() { int p = -1, last = -1; for (int i = 0; i < 11; ++ i) { long double dis = 100000; p = -1; for (int j = 0; j < n; ++ j) if (j != last && ~ cmp((b - a) ^ (ball[j].p - a)) && ~ cmp(ball[j].r - Line(a, b) % ball[j].p)) { long double tmp = sqrt(abs(! (ball[j].p - a) * ! (ball[j].p - a) - (Line(a, b) % ball[j].p) * (Line(a, b) % ball[j].p))) - sqrt(abs(ball[j].r * ball[j].r - (Line(a, b) % ball[j].p) * (Line(a, b) % ball[j].p))); if (cmp(dis - tmp) == 1) dis = tmp, p = j; } if (! ~ p || i == 10) break; last = p; if (i) cout << ' '; cout << p + 1; Point c = a + (b - a) / ! (b - a) * dis; Point d = ball[p].p + (c - ball[p].p) / ! (c - ball[p].p) * (! (a - ball[p].p) * ((a - ball[p].p) ^ (c - ball[p].p))); b = d * 2 - a, a = c; } if (~ p) cout << " etc."; cout << endl; }
public: void solve() { input(), process(); } } solver;
int main() { solver.solve(); return 0; }
|