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

#include <algorithm>
#include <assert.h>
#include <iostream>
#include <map>
#include <math.h>
#include <queue>
#include <set>
#include <stdio.h>
#include <string.h>
#include <string>
#include <vector>

using namespace std;
typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;
static const long double EPS = 1e-9;
static const long double PI = acos(-1.0);

#define REP(i, n) for (int i = 0; i < (int)(n); i++)
#define FOR(i, s, n) for (int i = (s); i < (int)(n); i++)
#define FOREQ(i, s, n) for (int i = (s); i <= (int)(n); i++)
#define FORIT(it, c)                                                           \\
  for (__typeof((c).begin()) it = (c).begin(); it != (c).end(); it++)
#define MEMSET(v, h) memset((v), h, sizeof(v))

#include <complex>

typedef complex<long double> Point;
typedef vector<Point> Polygon;

static const long double INF = 1e+10;

#define CURR(P, i) (P[i])
#define NEXT(P, i) (P[(i + 1) % P.size()])

struct Line : public vector<Point> {
  Line() { ; }
  Line(Point a, Point b) {
    push_back(a);
    push_back(b);
  }
};

namespace std {
bool operator<(const Point &lhs, const Point &rhs) {
  return lhs.real() == rhs.real() ? lhs.imag() < rhs.imag()
                                  : lhs.real() < rhs.real();
}
} // namespace std

inline long double cross(const Point &a, const Point &b) {
  return imag(conj(a) * b);
}

inline long double dot(const Point &a, const Point &b) {
  return real(conj(a) * b);
}

inline int ccw(Point a, Point b, Point c) {
  b -= a;
  c -= a;
  if (cross(b, c) > 0) {
    return 1;
  }
  if (cross(b, c) < 0) {
    return -1;
  }
  if (dot(b, c) < 0) {
    return 2;
  }
  if (norm(b) < norm(c)) {
    return -2;
  }
  return 0;
}

Point crosspointSS(const Line &l, const Line &m) {
  long double A = cross(l[1] - l[0], m[1] - m[0]);
  long double B = cross(l[1] - l[0], l[1] - m[0]);
  if (abs(A) < EPS && abs(B) < EPS) {
    assert(false);
    return m[0];
  }
  if (abs(A) < EPS) {
    assert(false);
  }
  return m[0] + B / A * (m[1] - m[0]);
}

Polygon ConvexCut(const Polygon &P, const Line &l) {
  Polygon Q;
  for (int i = 0; i < (int)P.size(); i++) {
    Point A = CURR(P, i), B = NEXT(P, i);
    if (ccw(l[0], l[1], A) != -1) {
      Q.push_back(A);
    }
    if (ccw(l[0], l[1], A) * ccw(l[0], l[1], B) < 0) {
      Q.push_back(crosspointSS(Line(A, B), l));
    }
  }
  return Q;
}

long double Area(const Polygon &p) {
  long double ret = 0.0;
  REP(i, p.size()) { ret += cross(CURR(p, i), NEXT(p, i)); }
  return ret / 2.0;
}

int n;
Polygon poly;

long double CutArea(long double theta) {
  Point vect = Point(cos(theta), sin(theta));
  Line l = Line(vect * -1000.0L, vect * 1000.0L);
  Polygon ps = ConvexCut(poly, l);
  return Area(ps);
}

int main() {
  while (scanf("%d", &n), n) {
    poly.clear();
    REP(i, n) {
      long double x, y;
      scanf("%Lf %Lf", &x, &y);
      poly.push_back(Point(x, y));
    }
    long double all = Area(poly);
    long double left = 0.0;
    long double right = PI;
    bool s = (CutArea(left) < all / 2.0);
    REP(iter, 200) {
      long double mid = (left + right) / 2.0;
      if ((CutArea(mid) < all / 2.0) == s) {
        left = mid;
      } else {
        right = mid;
      }
    }
    printf("%.16Lf %.16Lf\\n", 10 * cos(left) + 1e-17, 10 * sin(left) + 1e-17);
  }
}

Error: WA

Fixed submission:

#include <algorithm>
#include <assert.h>
#include <iostream>
#include <map>
#include <math.h>
#include <queue>
#include <set>
#include <stdio.h>
#include <string.h>
#include <string>
#include <vector>

using namespace std;
typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;
static const long double EPS = 1e-9;
static const long double PI = acos(-1.0);

#define REP(i, n) for (int i = 0; i < (int)(n); i++)
#define FOR(i, s, n) for (int i = (s); i < (int)(n); i++)
#define FOREQ(i, s, n) for (int i = (s); i <= (int)(n); i++)
#define FORIT(it, c)                                                           \\
  for (__typeof((c).begin()) it = (c).begin(); it != (c).end(); it++)
#define MEMSET(v, h) memset((v), h, sizeof(v))

#include <complex>

typedef complex<long double> Point;
typedef vector<Point> Polygon;

static const long double INF = 1e+10;

#define CURR(P, i) (P[i])
#define NEXT(P, i) (P[(i + 1) % P.size()])

struct Line : public vector<Point> {
  Line() { ; }
  Line(Point a, Point b) {
    push_back(a);
    push_back(b);
  }
};

namespace std {
bool operator<(const Point &lhs, const Point &rhs) {
  return lhs.real() == rhs.real() ? lhs.imag() < rhs.imag()
                                  : lhs.real() < rhs.real();
}
} // namespace std

inline long double cross(const Point &a, const Point &b) {
  return imag(conj(a) * b);
}

inline long double dot(const Point &a, const Point &b) {
  return real(conj(a) * b);
}

inline int ccw(Point a, Point b, Point c) {
  b -= a;
  c -= a;
  if (cross(b, c) > 0) {
    return 1;
  }
  if (cross(b, c) < 0) {
    return -1;
  }
  if (dot(b, c) < 0) {
    return 2;
  }
  if (norm(b) < norm(c)) {
    return -2;
  }
  return 0;
}

Point crosspointSS(const Line &l, const Line &m) {
  long double A = cross(l[1] - l[0], m[1] - m[0]);
  long double B = cross(l[1] - l[0], l[1] - m[0]);
  if (abs(A) < EPS && abs(B) < EPS) {
    assert(false);
    return m[0];
  }
  if (abs(A) < EPS) {
    assert(false);
  }
  return m[0] + B / A * (m[1] - m[0]);
}

Polygon ConvexCut(const Polygon &P, const Line &l) {
  Polygon Q;
  for (int i = 0; i < (int)P.size(); i++) {
    Point A = CURR(P, i), B = NEXT(P, i);
    if (ccw(l[0], l[1], A) != -1) {
      Q.push_back(A);
    }
    if (ccw(l[0], l[1], A) * ccw(l[0], l[1], B) < 0) {
      Q.push_back(crosspointSS(Line(A, B), l));
    }
  }
  return Q;
}

long double Area(const Polygon &p) {
  long double ret = 0.0;
  REP(i, p.size()) { ret += cross(CURR(p, i), NEXT(p, i)); }
  return ret / 2.0;
}

int n;
Polygon poly;
int main() {
  while (scanf("%d", &n), n) {
    poly.clear();
    REP(i, n) {
      long double x, y;
      scanf("%Lf %Lf", &x, &y);
      poly.push_back(Point(x, y));
    }
    long double all = Area(poly);
    long double left = 0.0;
    long double right = PI;
    REP(iter, 300) {
      long double mid = (left + right) / 2.0;
      Point vect = Point(cos(mid), sin(mid));
      Line l = Line(vect * -1000.0L, vect * 1000.0L);
      Polygon ps = ConvexCut(poly, l);
      long double larea = Area(ps);
      if (iter == 299) {
        assert(fabs(larea - all / 2.0) <= EPS);
      }
      if (larea < all / 2.0) {
        right = mid;
      } else {
        left = mid;
      }
    }
    printf("%.16Lf %.16Lf\\n", 10 * cos(left) + 1e-17, 10 * sin(left) + 1e-17);
  }
}