Problem p01698 (C++) — buggy submission, verdict: Time Limit Exceeded

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <iostream>
#include <queue>
#include <string>
#include <vector>

#define rep(i, n) for (int i = 0; i < (n); i++)
#define rrep(i, n) for (int i = (n)-1; i >= 0; i--)
#define all(X) (X).begin(), (X).end()

using namespace std;
typedef long long int ll;
typedef pair<int, int> P;

template <class T> bool chmax(T &a, const T &b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T> bool chmin(T &a, const T &b) {
  if (a > b) {
    a = b;
    return 1;
  }
  return 0;
}

template <class A, size_t N, class T> void Fill(A (&a)[N], const T &v) {
  fill((T *)a, (T *)(a + N), v);
}

const int INF = 0x3fffffff;

typedef pair<double, P> PP;

int N;
double px[205], py[205], pz[205];
double vx[205], vy[205], vz[205];
double r[205], vr[205];
double dist(int a, int b, double t) {
  double dx = (px[a] - px[b]) + t * (vx[a] - vx[b]);
  double dy = (py[a] - py[b]) + t * (vy[a] - vy[b]);
  double dz = (pz[a] - pz[b]) + t * (vz[a] - vz[b]);
  double dr = r[a] + r[b] - t * (vr[a] + vr[b]);
  return sqrt(dx * dx + dy * dy + dz * dz) - dr;
}

double alive[205];
priority_queue<PP> que;
void collision(int a, int b) {
  // ????????????????????????????±???????
  double l = 0, r = min(alive[a], alive[b]);
  rep(i, 100) {
    double m1 = (l + 2.0 * r) / 3.0;
    double m2 = (2.0 * l + r) / 3.0;
    if (dist(a, b, m1) > dist(a, b, m2)) {
      r = m1;
    } else {
      l = m2;
    }
  }
  if (dist(a, b, l) > 0.0)
    return;
  // ???????????¶???????????????????±???????
  l = 0.0;
  rep(i, 100) {
    double m = (l + r) / 2;
    if (dist(a, b, m) > 0.0) {
      l = m;
    } else {
      r = m;
    }
  }
  que.push(PP(-l, P(a, b)));
}

void solve() {
  while (!que.empty()) {
    double t = -que.top().first;
    int a = que.top().second.first;
    int b = que.top().second.second;
    que.pop();
    if (alive[a] > t && alive[b] > t) {
      alive[a] = t;
      alive[b] = t;
    }
  }
}

int main() {
  while (cin >> N, N) {
    rep(i, N) {
      cin >> px[i] >> py[i] >> pz[i];
      cin >> vx[i] >> vy[i] >> vz[i];
      cin >> r[i] >> vr[i];
      alive[i] = r[i] / vr[i];
    }
    rep(i, N) rep(j, i) collision(i, j);
    solve();
    rep(i, N) { printf("%.10f\\n", alive[i]); }
  }

  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <iostream>
#include <queue>
#include <string>
#include <vector>

#define rep(i, n) for (int i = 0; i < (n); i++)
#define rrep(i, n) for (int i = (n)-1; i >= 0; i--)
#define all(X) (X).begin(), (X).end()

using namespace std;
typedef long long int ll;
typedef pair<int, int> P;

template <class T> bool chmax(T &a, const T &b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T> bool chmin(T &a, const T &b) {
  if (a > b) {
    a = b;
    return 1;
  }
  return 0;
}

template <class A, size_t N, class T> void Fill(A (&a)[N], const T &v) {
  fill((T *)a, (T *)(a + N), v);
}

const int INF = 0x3fffffff;

typedef pair<double, P> PP;

int N;
double px[205], py[205], pz[205];
double vx[205], vy[205], vz[205];
double r[205], vr[205];
double dist(int a, int b, double t) {
  double dx = (px[a] - px[b]) + t * (vx[a] - vx[b]);
  double dy = (py[a] - py[b]) + t * (vy[a] - vy[b]);
  double dz = (pz[a] - pz[b]) + t * (vz[a] - vz[b]);
  double dr = r[a] + r[b] - t * (vr[a] + vr[b]);
  return sqrt(dx * dx + dy * dy + dz * dz) - dr;
}

double alive[205];
priority_queue<PP> que;
void collision(int a, int b) {
  // ????????????????????????????±???????
  double l = 0, r = min(alive[a], alive[b]);
  rep(i, 1000) {
    double m1 = (l + 2.0 * r) / 3.0;
    double m2 = (2.0 * l + r) / 3.0;
    if (dist(a, b, m1) > dist(a, b, m2)) {
      r = m1;
    } else {
      l = m2;
    }
  }
  if (dist(a, b, l) > 0.0)
    return;
  // ???????????¶???????????????????±???????
  l = 0.0;
  rep(i, 1000) {
    double m = (l + r) / 2;
    if (dist(a, b, m) > 0.0) {
      l = m;
    } else {
      r = m;
    }
  }
  que.push(PP(-l, P(a, b)));
}

void solve() {
  while (!que.empty()) {
    double t = -que.top().first;
    int a = que.top().second.first;
    int b = que.top().second.second;
    que.pop();
    if (alive[a] > t && alive[b] > t) {
      alive[a] = t;
      alive[b] = t;
    }
  }
}

int main() {
  while (cin >> N, N) {
    rep(i, N) {
      cin >> px[i] >> py[i] >> pz[i];
      cin >> vx[i] >> vy[i] >> vz[i];
      cin >> r[i] >> vr[i];
      alive[i] = r[i] / vr[i];
    }
    rep(i, N) rep(j, i) collision(i, j);
    solve();
    rep(i, N) { printf("%.10f\\n", alive[i]); }
  }

  return 0;
}