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

#include <algorithm>
#include <bitset>
#include <cctype>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <functional>
#include <iomanip>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <utility>
#include <vector>

using namespace std;

#define all(c) c.begin(), c.end()
#define rep(i, n) for (int i = 0; i < (int)n; i++)

typedef long long ll;
typedef complex<double> point;
typedef pair<int, int> pii;

// →↑←↓
const int dx[] = {1, 0, -1, 0};
const int dy[] = {0, -1, 0, 1};

const double EPS = 1e-9;

int main() {
  cout << fixed << setprecision(10);
  int N;
  cin >> N;
  vector<point> ps(N);
  for (int i = 0; i < N; i++) {
    cin >> ps[i].real() >> ps[i].imag();
  }
  if (N % 2 == 0) {
    point p = ps[0] + ps[N / 2];
    bool ok = true;
    for (int i = 0; i < N / 2; i++) {
      point np = ps[i] + ps[i + N / 2];
      if (abs(p - np) > EPS) {
        ok = false;
      }
    }
    if (ok) {
      cout << (p / 2.0).real() << " " << (p / 2.0).imag() << endl;
    } else {
      cout << "NA" << endl;
    }
  } else {
    cout << "NA" << endl;
  }
  return 0;
}

Error: WA

Fixed submission:

#include <algorithm>
#include <bitset>
#include <cassert>
#include <cctype>
#include <complex>
#include <cstdio>
#include <functional>
#include <iomanip>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <utility>
#include <vector>

using namespace std;

#define all(c) c.begin(), c.end()
#define rall(c) c.rbegin(), c.rend()
#define mp(a, b) make_pair((a), (b))
#define eq ==

typedef long long ll;
typedef complex<double> point;
typedef pair<int, int> pii;
typedef pair<point, point> line;
// →↑←↓
const int dx[] = {1, 0, -1, 0};
const int dy[] = {0, -1, 0, 1};

const double EPS = 1e-11;

namespace std {
bool operator<(const point &lhs, const point &rhs) {
  if (real(lhs) == real(rhs)) {
    return imag(lhs) < imag(rhs);
  } else {
    return real(lhs) < real(rhs);
  }
}
} // namespace std

// ベクタの長さ
double vector_length(point a) { return abs(a); }

// 二点間距離
double point_distance(point a, point b) { return abs(a - b); }

// 単位ベクトル
point unit_vector(point a) { return a / abs(a); }

// 法線ベクトル
pair<point, point> normal_vector(point a) {
  point n1 = a * point(0, 1);
  point n2 = a * point(0, -1);
  return make_pair(n1, n2);
}

// 点が一緒かどうか
bool point_eq(point a, point b) { return abs(a - b) < EPS; }
// 内積 (dot product) : a・b = |a||b|cosΘ
double dot(point a, point b) { return real(conj(a) * b); }

// 外積 (cross product) : a×b = |a||b|sinΘ
double cross(point a, point b) { return imag(conj(a) * b); }

// a1,a2を端点とする線分(la)とb1,b2を端点(lb)とする線分の交差判定
bool is_intersected_linesegment(line la, line lb) {
  point a1 = la.first, a2 = la.second;
  point b1 = lb.first, b2 = lb.second;
  return (cross(a2 - a1, b1 - a1) * cross(a2 - a1, b2 - a1) < EPS) &&
         (cross(b2 - b1, a1 - b1) * cross(b2 - b1, a2 - b1) < EPS);
}

// 2直線の直交判定 : a⊥b <=> dot(a, b) = 0
// みけんしょう
bool is_orthogonal(line a, line b) {
  return dot(a.first - a.second, b.first - b.second) < EPS;
}

// 2直線の平行判定 : a//b <=> cross(a, b) = 0
// みけんしょう
bool is_parallel(line a, line b) {
  return cross(a.first - a.second, b.first - b.second) < EPS;
}

// a1,a2を端点とする線分(la)とb1,b2を端点とする線分(lb)の交点計算
point intersection_point_linesegment(line la, line lb) {
  point a1 = la.first, a2 = la.second;
  point b1 = lb.first, b2 = lb.second;
  if (a1 == b1 or a1 == b2)
    return a1;
  if (a2 == b1 or a2 == b2)
    return a2;
  point b = b2 - b1;
  double d1 = abs(cross(b, a1 - b1));
  double d2 = abs(cross(b, a2 - b1));
  double t = d1 / (d1 + d2);
  return a1 + (a2 - a1) * t;
}

// a1,a2を通る直線とb1,b2を通る直線の交差判定
bool is_intersected_line(line la, line lb) { return not is_parallel(la, lb); }

// a1,a2を通る直線とb1,b2を通る直線の交点計算
point intersection_line(line la, line lb) {
  point a1 = la.first, a2 = la.second;
  point b1 = lb.first, b2 = lb.second;
  point a = a2 - a1, b = b2 - b1;
  return a1 + a * cross(b, b1 - a1) / cross(b, a);
}

// 点の進行方向
int ccw(point a, point b, point c) {
  b -= a;
  c -= a;
  if (cross(b, c) > 0)
    return +1; // counter clockwise
  if (cross(b, c) < 0)
    return -1; // clockwise
  if (dot(b, c) < 0)
    return +2; // c -- a -- b
  if (norm(b) < norm(c))
    return -2; // a -- b -- c
  return 0;
}
typedef vector<point> vertex;

// 多角形の面積
double vertex_area(vertex v) {
  double ret = 0;
  for (int i = 0; i < v.size(); i++) {
    ret += cross(v[i], v[(i + 1) % v.size()]);
  }
  return ret / 2;
}

unsigned long xor128() {
  static unsigned long x = 123456789, y = 362436069, z = 521288629,
                       w = 88675123;
  unsigned long t;
  t = (x ^ (x << 11));
  x = y;
  y = z;
  z = w;
  return (w = (w ^ (w >> 19)) ^ (t ^ (t >> 8)));
}

// 角からには未対応
point find_opposite_point(vertex v, point p, int where_is_point) {
  double total_area = vertex_area(v);
  vertex alr;
  alr.push_back(p);
  for (int i = 1; i < v.size(); i++) {
    int one = (where_is_point + i) % v.size();
    int two = (where_is_point + i + 1) % v.size();
    alr.push_back(v[one]);

    point vec;
    vec = v[two] - v[one];
    point u = unit_vector(vec);
    double len = abs(vec);

    double upper = len;
    double lower = 0;
    for (int j = 0; j < 100; j++) {
      // np is on one-two.
      double mid = (upper + lower) / 2;
      point np = v[one] + u * mid;
      alr.push_back(np);
      if (vertex_area(alr) > total_area / 2 - EPS) {
        upper = mid;
      } else {
        lower = mid;
      }
      alr.pop_back();
    }
    point np = v[one] + u * upper;
    alr.push_back(np);
    if (abs(vertex_area(alr) - total_area / 2) < EPS) {
      return np;
    }
    alr.pop_back();
    np = v[one] + u * lower;
    alr.push_back(np);
    if (abs(vertex_area(alr) - total_area / 2) < EPS) {
      return np;
    }
    alr.pop_back();
  }
  assert("nyan");
}

// 角からには未対応
point find_opposite_point_myan(vertex v, point p, int where_is_point) {
  double total_area = vertex_area(v);
  vertex alr;
  alr.push_back(p);
  for (int i = 1; i < v.size() - 1; i++) {
    int one = (where_is_point + i) % v.size();
    int two = (where_is_point + i + 1) % v.size();
    alr.push_back(v[one]);

    point vec;
    vec = v[two] - v[one];
    point u = unit_vector(vec);
    double len = abs(vec);

    double upper = len;
    double lower = 0;
    for (int j = 0; j < 100; j++) {
      // np is on one-two.
      double mid = (upper + lower) / 2;
      point np = v[one] + u * mid;
      alr.push_back(np);
      if (vertex_area(alr) > total_area / 2 - EPS) {
        upper = mid;
      } else {
        lower = mid;
      }
      alr.pop_back();
    }
    point np = v[one] + u * upper;
    alr.push_back(np);
    if (abs(vertex_area(alr) - total_area / 2) < EPS) {
      return np;
    }
    alr.pop_back();
  }
}

void cerr_line(line l) { cerr << l.first << " " << l.second << endl; }
int main() {
  cout << fixed << setprecision(10);
  int N;
  cin >> N;
  vertex ver;
  for (int i = 0; i < N; i++) {
    int X, Y;
    cin >> X >> Y;
    ver.push_back(point(X, Y));
  }
  vector<line> chop;
  for (int i = 0; i < ver.size(); i++) {
    point p = ver[i];
    point op = find_opposite_point_myan(ver, p, i);
    chop.push_back(line(p, op));
    cerr_line(line(p, op));
  }

  bool ok = true;
  bool first = true;
  point ret;
  for (int i = 0; i < chop.size(); i++) {
    for (int j = i + 1; j < chop.size(); j++) {
      if (is_intersected_linesegment(chop[i], chop[j])) {
        point p = intersection_point_linesegment(chop[i], chop[j]);
        cerr << p << endl;
        if (first) {
          ret = p;
          first = false;
        } else {
          if (abs(p - ret) > EPS)
            ok = false;
        }
      }
    }
  }

  if (ok) {
    cout << ret.real() << " " << ret.imag() << endl;
  } else {
    cout << "NA" << endl;
  }
  return 0;
}