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

#include <math.h>
#include <stdio.h>

const double eps = 1e-8;

int sgn(double d) {
  if (d > eps)
    return 1;
  if (d < -eps)
    return -1;
  return 0;
}

int main() {
  double d;
  while (scanf("%lf", &d) != EOF) {
    if (sgn(d) == 0)
      break;
    double x, y, vx, vy;
    scanf("%lf%lf%lf%lf", &x, &y, &vx, &vy);
    double b1 = x * vy - y * vx;
    if (sgn(b1) == 0) {
      if (sgn(vx * x) < 0 || sgn(vy * y) < 0) {
        double dis = sqrt(x * x + y * y);
        if (sgn(dis - d) > 0)
          printf("impossible\\n");
        else
          printf("%.6lf\\n", dis);
      } else {
        double dis = sqrt(x * x + y * y);
        dis = 2.0 - dis;
        if (sgn(dis - d) > 0)
          printf("impossible\\n");
        else
          printf("%.6lf\\n", dis);
      }
      continue;
    }
    printf("impossible\\n");
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <vector>
using namespace std;

const double eps = 1e-10;
const double pi = acos(-1.0);
const double inf = 10;

inline int sgn(double x) { return x < -eps ? -1 : x > eps; }
inline double sqr(double x) { return x * x; }

struct P {
  double x, y;
  P(double x = 0, double y = 0) : x(x), y(y){};
  P turn_right() const { return P(y, -x); }
  P turn_left() const { return P(-y, x); }
  double len() const { return sqrt(x * x + y * y); }
  friend bool operator==(const P &p1, const P &p2) {
    return sgn(p1.x - p2.x) == 0 && sgn(p1.y == p2.y) == 0;
  }
  friend P operator-(const P &p1, const P &p2) {
    return P(p1.x - p2.x, p1.y - p2.y);
  }
  friend P operator+(const P &p1, const P &p2) {
    return P(p1.x + p2.x, p1.y + p2.y);
  }
  friend P operator*(const P &p, double a) { return P(p.x * a, p.y * a); }
  friend P operator/(const P &p, double a) { return P(p.x / a, p.y / a); }
  friend inline double operator*(const P &p1, const P &p2) {
    return p1.x * p2.y - p1.y * p2.x;
  }
  friend double dist(const P &p1, const P &p2) {
    return sqrt((p1.x - p2.x) * (p1.x - p2.x) + (p1.y - p2.y) * (p1.y - p2.y));
  }
  friend inline double cross(const P &o, const P &a, const P &b) {
    return (a - o) * (b - o);
  }
};

struct line {
  P a, b;
  line() {}
  line(P a, P b) : a(a), b(b) {}
  friend int intersection(line l1, line l2, P &p) {
    if (l1.a == l1.b || l2.a == l2.b)
      return -1;
    double c1 = (l1.b - l1.a) * (l2.b - l2.a),
           c2 = (l2.a - l1.a) * (l2.b - l2.a);
    if (sgn(c1) == 0) {
      if (sgn(c2) == 0) {
        return 2;
      } else
        return 0;
    } else {
      p = l1.a + (l1.b - l1.a) * (c2 / c1);
      return 1;
    }
  }
};

struct seg {
  P a, b;
  seg(){};
  seg(P a, P b) : a(a), b(b) {}

  friend int intersection(seg s, line l, P &p) {
    P v1 = l.b - l.a, v2 = s.b - l.a, v3 = s.a - l.a, v4 = s.b - s.a;
    int sign = sgn((v2 * v1) * (v3 * v1));
    double t = (s.a * v4 + v4 * l.a) / (v1 * v4);
    p = l.a + (l.b - l.a) * t;
    return sign <= 0;
  }
  friend bool onseg(const P &p, const seg &s) {
    if (sgn(cross(p, s.a, s.b)) == 0)
      if (sgn(p.x - min(s.a.x, s.b.x)) >= 0 &&
          sgn(p.x - max(s.a.x, s.b.x)) <= 0)
        if (sgn(p.y - min(s.a.y, s.b.y)) >= 0 &&
            sgn(p.y - max(s.a.y, s.b.y)) <= 0)
          return 1;
    return 0;
  }
};

struct circle {
  P o;
  double r;
  circle() : r(0) {}
  circle(P o, double r = 0) : o(o), r(r){};
  friend int intersection(const circle &c, const seg &s, P &p1, P &p2) {
    if (sgn(dist(c.o, s.a) - c.r) < 0 && sgn(dist(c.o, s.b) - c.r) < 0) {
      return 0;
    }
    P v = (s.b - s.a).turn_right(), p;
    line l(c.o, c.o + v);
    if (intersection(s, l, p)) {
      double d1 = dist(c.o, s.a), d2 = dist(c.o, s.b),
             d3 = fabs((c.o - s.b) * (s.a - s.b)) / (s.a - s.b).len();
      int sign = sgn(d3 - c.r);
      if (sign < 0) {
        if (sgn(min(d1, d2) - c.r) < 0) {
          if (sgn(d1 - c.r) < 0) {
            P v1 = s.b - p;
            p1 = p + v1 * (sqrt(sqr(c.r) - sqr(d3)) / v1.len());
          } else {
            P v1 = s.a - p;
            p1 = p + v1 * (sqrt(sqr(c.r) - sqr(d3)) / v1.len());
          }
          return 1;
        } else {
          P v1 = s.a - p;
          p1 = p + v1 * (sqrt(sqr(c.r) - sqr(d3)) / v1.len());
          v1 = s.b - p;
          p2 = p + v1 * (sqrt(sqr(c.r) - sqr(d3)) / v1.len());
          return 2;
        }
      } else if (sign == 0) {
        p1 = p;
        return 3;
      } else
        return 0;
    } else {
      double d1 = dist(c.o, s.a), d2 = dist(c.o, s.b),
             d3 = fabs((c.o - s.b) * (s.a - s.b)) / (s.a - s.b).len();
      int sign = sgn(min(d1, d2) - c.r);
      if (sign < 0) {
        if (sgn(d1 - c.r) < 0) {
          P v1 = s.b - s.a;
          p1 = s.b + v1 * (sqrt(sqr(c.r) - sqr(d3)) - sqrt(sqr(d2) - sqr(d3))) /
                         v1.len();
        } else {
          P v1 = s.a - s.b;
          p1 = s.a + v1 * (sqrt(sqr(c.r) - sqr(d3)) - sqrt(sqr(d1) - sqr(d3))) /
                         v1.len();
        }
        return 1;
      }
      if (sign == 0) {
        p1 = sgn(d1 - c.r) == 0 ? s.a : s.b;
        return 1;
      } else
        return 0;
    }
  }
};

int reflection(P &p, P &d, line &l) {
  if (sgn(d * (l.a - l.b)) == 0)
    return 0;
  line k(p, p + d);
  P x;
  intersection(k, l, x);
  k.a = x, k.b = (l.a - l.b).turn_left() + x;
  double th = atan2(l.a.y - l.b.y, l.a.x - l.b.x);
  th += th - atan2(d.y, d.x);
  p = x;
  d.x = cos(th), d.y = sin(th);
  return 1;
}

double D;
double posx, posy;
double dx, dy;

int main() {

  while (cin >> D) {
    if (abs(D) < eps)
      return 0;
    cin >> posx >> posy;
    cin >> dx >> dy;

    circle e;
    e.r = 1;
    e.o = 0;

    double len0 = 0;
    seg ss;
    P p1, p2;

    P pp, dd;

    while (abs(dx) < 10 && abs(dy) < 10)
      dx *= inf, dy *= inf;
    pp.x = posx;
    pp.y = posy;
    dd.x = dx;
    dd.y = dy;

    P p0;
    p0.x = 0;
    p0.y = 0;
    double ans;

    int flag = 0;
    while (len0 <= D + eps) {
      while (abs(dd.x) < 10 && abs(dd.y) < 10)
        dd.x *= inf, dd.y *= inf;
      p1 = pp;
      p2 = pp + dd;

      ss.a = p1;
      ss.b = p2;

      if (onseg(p0, ss)) {
        ans = len0 + dist(p0, p1);
        if (ans < D + eps) {
          flag = 1;
          break;
        }
      }

      intersection(e, ss, p1, p2);
      P p;
      if (p1 == ss.a)
        p = ss.b;
      else
        p = ss.a;
      P l2p;
      if (sgn(p1.y) == 0) {
        l2p.x = p1.x + 1;
        l2p.y = 10;
      } else {
        l2p.x = p1.x + 1;
        l2p.y = p1.y - p1.x / p1.y;
      }
      line l;
      l.a = p1;
      l.b = l2p;
      p = p1;

      p1 = ss.a;
      p2 = ss.b;
      len0 += dist(p1, p);

      pp = p1;
      dd = p2 - p1;

      reflection(pp, dd, l);
    }
    if (flag)
      printf("%.8lf\\n", ans);
    else
      cout << "impossible" << endl;
  }
  return 0;
}