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

#include <bits/stdc++.h>
using namespace std;

typedef complex<double> P; // Point
typedef pair<P, P> L;      // Line, Segment

const double INF = 1e13;
const double EPS = 1e-10;
const double PI = 6.0 * asin(0.5);

namespace std {
bool operator<(const P &a, const P &b) {
  return fabs(real(a) - real(b)) < EPS ? imag(a) < imag(b) : real(a) < real(b);
}
bool operator==(const P &a, const P &b) {
  return fabs(real(a) - real(b)) < EPS && fabs(imag(a) - imag(b)) < EPS;
}
} // namespace std

double dot(P a, P b) { return real(conj(a) * b); }
double cross(P a, P b) { return imag(conj(a) * b); }
// 線分と点の交差判定
bool isIntersectSP(L s, P p) {
  return abs(s.first - p) + abs(s.second - p) - abs(s.second - s.first) < EPS;
}

int N;
L seg[1001];
P tp, pp;
int startid;

P getPoint(double dis, int di) {
  double r = 0.0;
  if (di == -1) {
    r = abs(seg[startid].first - tp);
  } else {
    r = abs(seg[startid].second - tp);
  }

  if (dis < r + EPS) {
    P v;
    if (di == -1) {
      v = seg[startid].first - tp;
      if (r < EPS)
        return seg[startid].first;
    } else {
      v = seg[startid].second - tp;
      if (r < EPS)
        return seg[startid].second;
    }
    //  cout << "getPoint " << v << " " << tp << " "<< r << " " << dis << endl;
    return tp + v / abs(v) * dis;
  }

  for (int i = startid + di; 0 <= i && i < N - 1; i += di) {
    double s = dis - r;
    r += abs(seg[i].first - seg[i].second);
    double kr = abs(seg[i].first - seg[i].second);
    if (dis < r + EPS) {
      P v;
      if (di == -1) {
        v = seg[i].first - seg[i].second;
        return seg[i].second + v / kr * s;
      } else {
        v = seg[i].second - seg[i].first;
        return seg[i].first + v / kr * s;
      }
    }
  }
  return P(INF, INF);
}

double solve(int bit, int tv, int pv, double now, P pnow) {
  if (bit == 3)
    return now;
  double res = 1e20;
  for (int i = 0; i < 2; i++) {
    if (bit & (1 << i))
      continue;

    double st = now, ed = 1000000000.0;
    P pnext = pnow;
    while (fabs(ed - st) > EPS) {
      double t = (st + ed) / 2.0;
      int di = i == 0 ? -1 : 1;
      double dis = (double)tv * t;
      P p = getPoint(dis, di);

      //  cout << t << " " << dis << " " <<pnow << " -> " << p << endl;

      if (p == P(INF, INF)) {
        ed = t;
      } else {
        double disp = (double)pv * (t - now);
        double ky = abs(p - pnow);
        //	cout << "disp " << disp << " ky " << ky << endl;
        if (disp + EPS > ky) {
          pnext = p;
          ed = t;
        } else {
          st = t;
        }
      }
    }
    //      cout << pnow << " -> " << pnext << endl;
    // cout << st << " " << now << endl;
    res = min(res, solve(bit | (1 << i), tv, pv, st, pnext));
  }
  return res;
}

int main() {
  /* cout << 1000 << endl;
  for(int i=0;i<1000;i++){
    cout << i*10 << " " << 0 << endl;
  }
  cout <<"0 0 1" << endl;
  cout << "10000 0 1" <<endl;
  return 0;
  */
  cin >> N;
  P pr;
  for (int i = 0; i < N; i++) {
    int x, y;
    cin >> x >> y;
    seg[i].first = P(x, y);
    if (i)
      seg[i - 1].second = P(x, y);
  }

  int tx, ty, tv;
  int px, py, pv;
  cin >> tx >> ty >> tv;
  tp = P(tx, ty);
  for (int i = 0; i < N - 1; i++) {
    if (isIntersectSP(seg[i], tp)) {
      startid = i;
      break;
    }
  }
  cin >> px >> py >> pv;
  pp = P(px, py);

  printf("%.9lf\\n", solve(0, tv, pv, 0.0, pp));
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;

typedef complex<double> P; // Point
typedef pair<P, P> L;      // Line, Segment

const double EPS = 1e-12;
const double PI = 6.0 * asin(0.5);

namespace std {
bool operator<(const P &a, const P &b) {
  return fabs(real(a) - real(b)) < EPS ? imag(a) < imag(b) : real(a) < real(b);
}
bool operator==(const P &a, const P &b) {
  return fabs(real(a) - real(b)) < EPS && fabs(imag(a) - imag(b)) < EPS;
}
} // namespace std

double dot(P a, P b) { return real(conj(a) * b); }
double cross(P a, P b) { return imag(conj(a) * b); }
// 線分と点の交差判定
bool isIntersectSP(L s, P p) {
  return abs(s.first - p) + abs(s.second - p) - abs(s.second - s.first) < EPS;
}

int N;
L seg[1001];
P tp, pp;
int startid;

P getPoint(double dis, int di) {
  double r = 0.0;
  if (di == -1) {
    r = abs(seg[startid].first - tp);
  } else {
    r = abs(seg[startid].second - tp);
  }

  if (dis < r + EPS) {
    P v;
    if (di == -1) {
      v = seg[startid].first - tp;
      if (r < EPS)
        return seg[startid].first;
    } else {
      v = seg[startid].second - tp;
      if (r < EPS)
        return seg[startid].second;
    }
    //  cout << "getPoint " << v << " " << tp << " "<< r << " " << dis << endl;
    return tp + v / abs(v) * dis;
  }

  for (int i = startid + di; 0 <= i && i < N - 1; i += di) {
    double s = dis - r;
    r += abs(seg[i].first - seg[i].second);
    double kr = abs(seg[i].first - seg[i].second);
    if (dis < r + EPS) {
      P v;
      if (di == -1) {
        v = seg[i].first - seg[i].second;
        return seg[i].second + v / kr * s;
      } else {
        v = seg[i].second - seg[i].first;
        return seg[i].first + v / kr * s;
      }
    }
  }
  return P(-1e19, -1e19);
}

double solve(int bit, int tv, int pv, double now, P pnow) {
  if (bit == 3)
    return now;
  double res = 1e20;
  for (int i = 0; i < 2; i++) {
    if (bit & (1 << i))
      continue;

    double st = now, ed = 1000000000.0;
    P pnext = pnow;
    while (fabs(ed - st) > EPS) {
      double t = (st + ed) / 2.0;
      int di = i == 0 ? -1 : 1;
      double dis = (double)tv * t;
      P p = getPoint(dis, di);

      //  cout << t << " " << dis << " " <<pnow << " -> " << p << endl;

      if (p == P(-1e19, -1e19)) {
        ed = t;
      } else {
        double disp = (double)pv * (t - now);
        double ky = abs(p - pnow);
        //	cout << "disp " << disp << " ky " << ky << endl;
        if (disp + EPS > ky) {
          pnext = p;
          ed = t;
        } else {
          st = t;
        }
      }
    }
    //      cout << pnow << " -> " << pnext << endl;
    // cout << st << " " << now << endl;
    res = min(res, solve(bit | (1 << i), tv, pv, st, pnext));
  }
  return res;
}

int main() {
  cin >> N;
  P pr;
  for (int i = 0; i < N; i++) {
    int x, y;
    cin >> x >> y;
    seg[i].first = P(x, y);
    if (i)
      seg[i - 1].second = P(x, y);
  }

  int tx, ty, tv;
  int px, py, pv;
  cin >> tx >> ty >> tv;
  tp = P(tx, ty);
  for (int i = 0; i < N - 1; i++) {
    if (isIntersectSP(seg[i], tp))
      startid = i;
  }
  cin >> px >> py >> pv;
  pp = P(px, py);

  printf("%.9lf\\n", solve(0, tv, pv, 0.0, pp));
}