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

#include <bits/stdc++.h>

using namespace std;

namespace {

const double EPS = 1e-8;

struct Point {
  double x, y;
  Point() {}
  Point(double x, double y) : x(x), y(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*(double k) const { return Point(k * x, k * y); }
  Point operator/(double k) const { return Point(x / k, y / k); }
};
double dot(const Point &a, const Point &b) { return a.x * b.x + a.y * b.y; }
double cross(const Point &a, const Point &b) { return a.x * b.y - a.y * b.x; }
double norm(const Point &a) { return sqrt(dot(a, a)); }
Point rot90(const Point &p) { return Point(-p.y, p.x); } // 反時計回りに90度回転
double angle(const Point &a) {
  return atan2(a.y, a.x);
} // x軸を反時計回りに何ラジアン回転させれば点aに乗るか
ostream &operator<<(ostream &os, const Point &p) {
  return os << "(" << p.x << "," << p.y << ")";
}
istream &operator>>(istream &is, Point &p) { return is >> p.x >> p.y; }

int ccw(Point a, Point b, Point c) {
  b = b - a;
  c = c - a;
  if (cross(b, c) > EPS)
    return +1; // a,b,cの順に反時計周り
  if (cross(b, c) < -EPS)
    return -1; // a,b,cの順に時計周り
  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 直線
}

struct Line {
  Point a, b;
  Line() {}
  Line(const Point &a, const Point &b) : a(a), b(b) {}
};
ostream &operator<<(ostream &os, const Line &l) {
  return os << "Line(" << l.a << "," << l.b << ")";
}
Point crosspoint(const Line &s, const Line &t) {
  double d = cross(t.b - t.a, s.b - s.a);
  assert(abs(d) >= EPS);
  return s.a + (s.b - s.a) * cross(t.b - t.a, t.b - s.a) / d;
}
bool parallel(const Line &s, const Line &t) {
  return abs(cross(s.b - s.a, t.b - t.a)) < EPS;
}

template <class T> ostream &operator<<(ostream &os, const vector<T> &vs) {
  if (vs.empty())
    return os << "[]";
  os << "[" << vs[0];
  for (int i = 1; i < vs.size(); i++)
    os << " " << vs[i];
  return os << "]";
}

int N, M;
vector<Point> V;
vector<Point> L;
bool input() {
  cin >> N >> M;
  if (N == 0 && M == 0)
    return false;
  V.clear();
  V.resize(N);
  L.clear();
  L.resize(M);
  for (int i = 0; i < N; i++)
    cin >> V[i];
  for (int j = 0; j < M; j++)
    cin >> L[j];
  return true;
}

Line midline(Point a, Point b) {
  Point m = (a + b) / 2;
  Point v = b - m;
  return Line(m, m + rot90(v));
}

typedef vector<Point> Polygon;
double area(const Polygon &vs) {
  if (vs.size() < 3)
    return 0;
  double r = 0;
  for (int i = 0; i < vs.size(); i++) {
    const Point &a = vs[i];
    const Point &b = vs[(i + 1) % vs.size()];
    r += cross(a, b);
  }
  return r / 2;
}

struct angle_comp {
  Point p;
  angle_comp(Point p) : p(p) {}
  bool operator()(Point a, Point b) { return angle(a - p) < angle(b - p); }
};

void solve() {
  for (int i = 0; i < M; i++) {
    vector<Point> P = V;
    for (int j = 0; j < M; j++) {
      if (i == j)
        continue;
      Line m = midline(L[i], L[j]);
      vector<Point> add;
      int n = P.size();
      for (int k = 0; k < n; k++) {
        Line e(P[k], P[(k + 1) % n]);
        if (parallel(m, e))
          continue;
        Point p = crosspoint(m, e);
        if (ccw(e.a, p, e.b) == -2) {
          add.push_back(p);
        }
      }
      vector<Point> nP = add;
      for (int k = 0; k < n; k++) {
        Line c(L[i], P[k]);
        if (!parallel(c, m) && ccw(L[i], crosspoint(c, m), P[k]) == -2)
          continue;
        nP.push_back(P[k]);
      }
      sort(nP.begin(), nP.end(), angle_comp(L[i]));
      P = nP;
    }
    printf("%.12lf\\n", area(P));
  }
}
} // namespace

int main() {
  while (input())
    solve();
  return 0;
}

Error: WA

Fixed submission:

#include <bits/stdc++.h>

using namespace std;

namespace {

const double EPS = 1e-8;

struct Point {
  double x, y;
  Point() {}
  Point(double x, double y) : x(x), y(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*(double k) const { return Point(k * x, k * y); }
  Point operator/(double k) const { return Point(x / k, y / k); }
};
double dot(const Point &a, const Point &b) { return a.x * b.x + a.y * b.y; }
double cross(const Point &a, const Point &b) { return a.x * b.y - a.y * b.x; }
double norm(const Point &a) { return sqrt(dot(a, a)); }
Point rot90(const Point &p) { return Point(-p.y, p.x); } // 反時計回りに90度回転
double angle(const Point &a) {
  return atan2(a.y, a.x);
} // x軸を反時計回りに何ラジアン回転させれば点aに乗るか
ostream &operator<<(ostream &os, const Point &p) {
  return os << "(" << p.x << "," << p.y << ")";
}
istream &operator>>(istream &is, Point &p) { return is >> p.x >> p.y; }

int ccw(Point a, Point b, Point c) {
  b = b - a;
  c = c - a;
  if (cross(b, c) > EPS)
    return +1; // a,b,cの順に反時計周り
  if (cross(b, c) < -EPS)
    return -1; // a,b,cの順に時計周り
  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 直線
}

struct Line {
  Point a, b;
  Line() {}
  Line(const Point &a, const Point &b) : a(a), b(b) {}
};
ostream &operator<<(ostream &os, const Line &l) {
  return os << "Line(" << l.a << "," << l.b << ")";
}
Point crosspoint(const Line &s, const Line &t) {
  double d = cross(t.b - t.a, s.b - s.a);
  assert(abs(d) >= EPS);
  return s.a + (s.b - s.a) * cross(t.b - t.a, t.b - s.a) / d;
}
bool parallel(const Line &s, const Line &t) {
  return abs(cross(s.b - s.a, t.b - t.a)) < EPS;
}

template <class T> ostream &operator<<(ostream &os, const vector<T> &vs) {
  if (vs.empty())
    return os << "[]";
  os << "[" << vs[0];
  for (int i = 1; i < vs.size(); i++)
    os << " " << vs[i];
  return os << "]";
}

int N, M;
vector<Point> V;
vector<Point> L;
bool input() {
  cin >> N >> M;
  if (N == 0 && M == 0)
    return false;
  V.clear();
  V.resize(N);
  L.clear();
  L.resize(M);
  for (int i = 0; i < N; i++)
    cin >> V[i];
  for (int j = 0; j < M; j++)
    cin >> L[j];
  return true;
}

Line midline(Point a, Point b) {
  Point m = (a + b) / 2;
  Point v = b - m;
  return Line(m, m + rot90(v));
}

typedef vector<Point> Polygon;
double area(const Polygon &vs) {
  assert(vs.size() >= 3);
  double r = 0;
  for (int i = 0; i < vs.size(); i++) {
    const Point &a = vs[i];
    const Point &b = vs[(i + 1) % vs.size()];
    r += cross(a, b);
  }
  return r / 2;
}

struct angle_comp {
  Point p;
  angle_comp(Point p) : p(p) {}
  bool operator()(Point a, Point b) { return angle(a - p) < angle(b - p); }
};

void solve() {
  for (int i = 0; i < M; i++) {
    vector<Point> P = V;
    for (int j = 0; j < M; j++) {
      if (i == j)
        continue;
      Line m = midline(L[i], L[j]);
      vector<Point> add;
      int n = P.size();
      for (int k = 0; k < n; k++) {
        Line e(P[k], P[(k + 1) % n]);
        if (parallel(m, e))
          continue;
        Point p = crosspoint(m, e);
        if (ccw(e.a, p, e.b) == -2) {
          add.push_back(p);
        }
      }
      // assert(add.size() == 2);
      vector<Point> nP = add;
      for (int k = 0; k < n; k++) {
        Line c(L[i], P[k]);
        if (parallel(c, m))
          continue;
        if (ccw(L[i], crosspoint(c, m), P[k]) == -2)
          continue;
        nP.push_back(P[k]);
      }
      sort(nP.begin(), nP.end(), angle_comp(L[i]));
      P = nP;
    }
    printf("%.12lf\\n", area(P));
  }
}
} // namespace

int main() {
  while (input())
    solve();
  return 0;
}