Problem p00639 (C++) — buggy submission, verdict: Runtime Error

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <vector>
using namespace std;

const double EPS = 1e-9;

struct point {
  double x, y;
  point(double x = 0.0, double y = 0.0) : x(x), y(y) {}
  point(const point &p) : x(p.x), y(p.y) {}

  point operator+(const point &p) const { return point(x + p.x, y + p.y); }

  point operator-(const point &p) const { return point(x - p.x, y - p.y); }

  point operator*(const double s) const { return point(x * s, y * s); }

  point operator*(const point &p) const {
    return point(x * p.x - y * p.y, x * p.y + y * p.x);
  }

  point operator/(const double s) const { return point(x / s, y / s); }

  bool operator<(const point &p) const {
    return x + EPS < p.x || abs(x - p.x) < EPS && y + EPS < p.y;
  }

  bool operator==(const point &p) const {
    return abs(x - p.x) < EPS && abs(y - p.y) < EPS;
  }
};

inline point rotate90(const point &p) { return point(-p.y, p.x); }

inline point rotate(const point &p, const double theta) {
  const double s = sin(theta), c = cos(theta);
  return point(c * p.x - s * p.y, s * p.x + c * p.y);
}

inline double angle(const point &p) { return atan2(p.y, p.x); }

inline double abs(const point &p) { return sqrt(p.x * p.x + p.y * p.y); }

inline double norm(const point &p) { return p.x * p.x + p.y * p.y; }

inline double dot(const point &l, const point &r) {
  return l.x * r.x + l.y * r.y;
}

inline double cross(const point &l, const point &r) {
  return l.x * r.y - l.y * r.x;
}

struct line {
  point a, b;
  line(point a, point b) : a(a), b(b) {}
};

struct segment {
  point a, b;
  segment(point a, point b) : a(a), b(b) {}
};

struct circle {
  point c;
  double r;
  circle(point c, double r) : c(c), r(r) {}
};

typedef vector<point> polygon;

inline int ccw(const point &a, point b, point c) {
  b = b - a;
  c = c - a;
  const double tmp = cross(b, c);
  if (tmp > EPS)
    return 1; // ccw
  if (tmp < -EPS)
    return -1; // cw
  if (dot(b, c) < 0)
    return 2; // c, a, b 順に一直線上
  if (norm(b) < norm(c))
    return -2; // a, b, c 順に一直線上
  return 0;    // a, c, b 順で一直線上
}

inline point projection(const line &l, const point &p) {
  const point dif = l.b - l.a;
  const double tmp = dot(p - l.a, dif) / norm(dif);
  return l.a + dif * tmp;
}

inline bool intersect(const segment &s, const point &p) {
  return ccw(s.a, s.b, p) == 0;
}

inline double dist(const line &l, const point &p) {
  return abs(cross((l.b - l.a), (p - l.a))) / abs(l.b - l.a);
}

inline double dist(const segment &s, const point &p) {
  if (dot((s.b - s.a), (p - s.a)) < 0)
    return abs(p - s.a);
  if (dot((s.a - s.b), (p - s.b)) < 0)
    return abs(p - s.b);
  return dist(line(s.a, s.b), p);
}

inline double dist(const point &a, const point &b) { return abs(a - b); }

inline bool intersect(const circle &c, const segment &s) {
  return dist(s, c.c) < c.r + EPS;
}

inline vector<point> crosspoint(const circle &c, const line &l) {
  vector<point> res;
  const point h = projection(l, c.c);
  const double d = abs(h - c.c);
  if (d > c.r - EPS) {
    res.push_back(h);
  } else if (d <= c.r - EPS) {
    point v = l.b - l.a;
    v = v * sqrt(c.r * c.r - d * d) / abs(v);
    res.push_back(h + v);
    res.push_back(h - v);
  }

  return res;
}

inline vector<point> crosspoint(const circle &c, const segment &s) {
  vector<point> res;
  vector<point> tmp = crosspoint(c, line(s.a, s.b));
  for (int i = 0; i < tmp.size(); ++i)
    if (intersect(s, tmp[i]))
      res.push_back(tmp[i]);

  return res;
}

int main() {
  for (double d; scanf("%lf", &d) && d > 0.0;) {
    double px, py, vx, vy;
    scanf("%lf %lf %lf %lf", &px, &py, &vx, &vy);

    point lab(0.0, 0.0);
    circle reflect_circle(lab, 1.0);

    point p(px, py);
    point v(vx, vy);
    v = v * (d / abs(v));
    segment seg(p, p + v);

    double ans = -1.0;
    bool first = true;

    while (true) {
      if (intersect(seg, lab)) {
        ans = dist(seg.a, lab);
        break;
      }

      vector<point> crosspoints = crosspoint(reflect_circle, seg);
      if (first && crosspoints.size() == 1) {
        const point c_point = crosspoint(reflect_circle, seg)[0];
        lab = c_point + (c_point - lab);
        first = false;
      } else {
        break;
      }
    }

    if (ans < 0.0) {
      puts("impossible");
    } else {
      printf("%.10lf\\n", ans);
    }
  }

  return EXIT_SUCCESS;
}

Error: WA

Fixed submission:

#include <algorithm>
#include <array>
#include <bitset>
#include <cassert>
#include <cctype>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque>
#include <functional>
#include <iostream>
#include <iterator>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <random>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <tuple>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>
using namespace std;

const double EPS = 1e-9;

struct point {
  double x, y;
  point(double x = 0.0, double y = 0.0) : x(x), y(y) {}
  point(const point &p) : x(p.x), y(p.y) {}

  point operator+(const point &p) const { return point(x + p.x, y + p.y); }

  point operator-(const point &p) const { return point(x - p.x, y - p.y); }

  point operator*(const double s) const { return point(x * s, y * s); }

  point operator*(const point &p) const {
    return point(x * p.x - y * p.y, x * p.y + y * p.x);
  }

  point operator/(const double s) const { return point(x / s, y / s); }

  bool operator<(const point &p) const {
    return x + EPS < p.x || abs(x - p.x) < EPS && y + EPS < p.y;
  }

  bool operator==(const point &p) const {
    return abs(x - p.x) < EPS && abs(y - p.y) < EPS;
  }
};

inline point rotate90(const point &p) { return point(-p.y, p.x); }

inline point rotate(const point &p, const double theta) {
  const double s = sin(theta), c = cos(theta);
  return point(c * p.x - s * p.y, s * p.x + c * p.y);
}

inline double angle(const point &p) { return atan2(p.y, p.x); }

inline double abs(const point &p) { return sqrt(p.x * p.x + p.y * p.y); }

inline double norm(const point &p) { return p.x * p.x + p.y * p.y; }

inline double dot(const point &l, const point &r) {
  return l.x * r.x + l.y * r.y;
}

inline double cross(const point &l, const point &r) {
  return l.x * r.y - l.y * r.x;
}

struct line {
  point a, b;
  line(point a, point b) : a(a), b(b) {}
};

struct segment {
  point a, b;
  segment(point a, point b) : a(a), b(b) {}
};

struct circle {
  point c;
  double r;
  circle(point c, double r) : c(c), r(r) {}
};

typedef vector<point> polygon;

inline int ccw(const point &a, point b, point c) {
  b = b - a;
  c = c - a;
  const double tmp = cross(b, c);
  if (tmp > EPS)
    return 1; // ccw
  if (tmp < -EPS)
    return -1; // cw
  if (dot(b, c) < 0)
    return 2; // c, a, b 順に一直線上
  if (norm(b) < norm(c))
    return -2; // a, b, c 順に一直線上
  return 0;    // a, c, b 順で一直線上
}

inline point projection(const line &l, const point &p) {
  const point dif = l.b - l.a;
  const double tmp = dot(p - l.a, dif) / norm(dif);
  return l.a + dif * tmp;
}

inline bool intersect(const segment &s, const point &p) {
  return ccw(s.a, s.b, p) == 0;
}

inline double dist(const line &l, const point &p) {
  return abs(cross((l.b - l.a), (p - l.a))) / abs(l.b - l.a);
}

inline double dist(const segment &s, const point &p) {
  if (dot((s.b - s.a), (p - s.a)) < 0)
    return abs(p - s.a);
  if (dot((s.a - s.b), (p - s.b)) < 0)
    return abs(p - s.b);
  return dist(line(s.a, s.b), p);
}

inline double dist(const point &a, const point &b) { return abs(a - b); }

inline bool intersect(const circle &c, const segment &s) {
  return dist(s, c.c) < c.r + EPS;
}

inline vector<point> crosspoint(const circle &c, const line &l) {
  vector<point> res;
  const point h = projection(l, c.c);
  const double d = abs(h - c.c);
  if (d > c.r - EPS) {
    res.push_back(h);
  } else if (d <= c.r - EPS) {
    point v = l.b - l.a;
    v = v * sqrt(c.r * c.r - d * d) / abs(v);
    res.push_back(h + v);
    res.push_back(h - v);
  }

  return res;
}

inline vector<point> crosspoint(const circle &c, const segment &s) {
  vector<point> res;
  vector<point> tmp = crosspoint(c, line(s.a, s.b));
  for (int i = 0; i < tmp.size(); ++i)
    if (intersect(s, tmp[i]))
      res.push_back(tmp[i]);

  return res;
}

int main() {
  for (double d; scanf("%lf", &d) && d > 0.0;) {
    double px, py, vx, vy;
    scanf("%lf %lf %lf %lf", &px, &py, &vx, &vy);

    point lab(0.0, 0.0);
    circle reflect_circle(lab, 1.0);

    point p(px, py);
    point v(vx, vy);
    v = v * (d / abs(v));
    segment seg(p, p + v);

    double ans = -1.0;
    bool first = true;

    while (true) {
      if (intersect(seg, lab)) {
        ans = dist(seg.a, lab);
        break;
      }

      vector<point> crosspoints = crosspoint(reflect_circle, seg);
      if (first && intersect(reflect_circle, seg)) {
        const point c_point = crosspoint(reflect_circle, seg)[0];
        lab = c_point + (c_point - lab);
        first = false;
      } else {
        break;
      }
    }

    if (ans < 0.0) {
      puts("impossible");
    } else {
      printf("%.10lf\\n", ans);
    }
  }

  return EXIT_SUCCESS;
}