// // Problem: Meteor Stream // Solution by: MORI Shingo // O(n^2 logn) // // implement 29min // #include #include #include #include #include #include #include #include #include #include #include #include using namespace std; typedef long long ll; typedef unsigned int uint; typedef unsigned long long ull; static const long double EPS = 1e-9; static const long double PI = acos(-1.0); #define REP(i, n) for (int i = 0; i < (int)(n); i++) #define FOR(i, s, n) for (int i = (s); i < (int)(n); i++) #define FOREQ(i, s, n) for (int i = (s); i <= (int)(n); i++) #define FORIT(it, c) for (__typeof((c).begin())it = (c).begin(); it != (c).end(); it++) #define MEMSET(v, h) memset((v), h, sizeof(v)) struct Sphere { vector p; vector v; long double r; long double vr; Sphere() : p(3), v(3), r(0.0), vr(0.0) {;} Sphere(long double x, long double y, long double z, long double vx, long double vy, long double vz, long double r, long double vr) : p{x, y, z}, v{ vx, vy, vz }, r(r), vr(vr) {;} }; struct Input { int n; vector spheres; }; namespace Solver { bool visit[1000]; struct Event { long double t; vector indexes; Event() {;} Event(long double t, int i) : t(t), indexes{i} {;} Event(long double t, int i, int j) : t(t), indexes{i, j} {;} bool operator<(const Event &rhs) const { return t > rhs.t; } }; long double square(long double x) { return x * x; } Sphere diff(const Sphere &lhs, const Sphere &rhs) { Sphere ret; REP(i, 3) { ret.p[i] = lhs.p[i] - rhs.p[i]; ret.v[i] = lhs.v[i] - rhs.v[i]; } ret.r = lhs.r + rhs.r; ret.vr = lhs.vr + rhs.vr; return ret; } vector QuadraticEquation(long double a, long double b, long double c) { vector ret; long double d = b * b - 4 * a * c; if (a == 0) { if (b == 0) { assert(c != 0); } else { ret.push_back(-c / b); } } else if (d >= 0) { ret.push_back((-b - sqrt(d)) / (2.0 * a)); ret.push_back((-b + sqrt(d)) / (2.0 * a)); } return ret; } vector solve(const Input &input) { const int n = input.n; MEMSET(visit, false); priority_queue que; REP(i, n) { const Sphere &s1 = input.spheres[i]; que.push(Event(s1.r / s1.vr, i)); FOR(j, i + 1, n) { const Sphere &s2 = input.spheres[j]; Sphere s = diff(s1, s2); long double a = square(s.v[0]) + square(s.v[1]) + square(s.v[2]) - square(s.vr); long double b = 2.0 * (s.p[0] * s.v[0] + s.p[1] * s.v[1] + s.p[2] * s.v[2] + s.r * s.vr); long double c = square(s.p[0]) + square(s.p[1]) + square(s.p[2]) - square(s.r); vector eq = QuadraticEquation(a, b, c); FORIT(it, eq) { if (*it <= 0.0) { continue; } que.push(Event(*it, i, j)); break; } } } vector ans(n); while (!que.empty()) { Event e = que.top(); que.pop(); FORIT(it, e.indexes) { if (visit[*it]) { goto next; } } FORIT(it, e.indexes) { ans[*it] = e.t; visit[*it] = true; } next:; } return ans; } } int main() { int n; int test_case = 0; Input input; while (scanf("%d", &n) > 0 && n) { test_case++; input.n = n; input.spheres = vector(n); REP(i, n) { long double x, y, z, vx, vy, vz, r, vr; scanf("%Lf %Lf %Lf %Lf %Lf %Lf %Lf %Lf", &x, &y, &z, &vx, &vy, &vz, &r, &vr); input.spheres[i] = Sphere(x, y, z, vx, vy, vz, r, vr); } vector ans = Solver::solve(input); REP(i, n) { printf("%.10Lf\n", ans[i]); } } assert(test_case <= 100); }