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

#include <cmath>
#include <cstdlib>
#include <iostream>
#include <vector>
using namespace std;

constexpr long double EPS = 1e-7;

struct point {
  long double x, y;
  point(long double x = 0.0, long 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*(long double s) const { return point(x * s, y * s); }
};

long double dot(const point &a, const point &b) {
  return a.x * b.x + a.y * b.y;
}

long double cross(const point &a, const point &b) {
  return a.x * b.y - a.y * b.x;
}

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

int ccw(const point &a, point b, point c) {
  b = b - a;
  c = c - a;
  const long double t = cross(b, c);
  if (t > EPS)
    return 1;
  if (t < -EPS)
    return -1;
  if (dot(b, c) < 0)
    return 2;
  if (norm(b) < norm(c))
    return -2;
  return 0;
}

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

struct line {
  point a, b;
  line(const point &a_, const point &b_) : a(a_), b(b_) {}
};

point crosspoint(const line &a, const line &b) {
  const long double t = cross(a.b - a.a, b.b - b.a);
  if (abs(t) < EPS)
    return a.a;
  return b.a + (b.b - b.a) * cross(a.b - a.a, a.a - b.a) * (1 / t);
}

typedef vector<point> polygon;

long double area(const polygon &p) {
  const int n = p.size();
  if (n < 3)
    return 0.0;

  long double res = cross(p[n - 1], p[0]);
  for (int i = 1; i < n; ++i) {
    res += cross(p[i - 1], p[i]);
  }
  return abs(res) * 0.5;
}

polygon convex_cut(const polygon &p, const line &l) {
  const int n = p.size();
  polygon res;
  for (int i = 0; i < n; ++i) {
    const int next = (i + 1) % n;
    const int tmp = ccw(l.a, l.b, p[i]);
    if (tmp != -1)
      res.emplace_back(p[i]);

    if (tmp * ccw(l.a, l.b, p[next]) < 0) {
      res.emplace_back(crosspoint(l, line(p[i], p[next])));
    }
  }

  return res;
}

bool ok(const point &g, const polygon &p) {
  const long double S_half = area(p) / 2.0;
  for (long double theta = 0; theta < M_PI; theta += 0.01) {
    const long double S =
        area(convex_cut(p, line(g, g + rotate(point(10, 0), theta))));
    if (abs((S_half - S) / S_half) > EPS)
      return false;
  }

  return true;
}

int main() {
  cin.tie(nullptr);
  ios::sync_with_stdio(false);
  cout.precision(5);
  cout.flags(ios::fixed);

  int n;
  cin >> n;

  point g(0, 0);
  polygon p;
  p.reserve(n);
  for (int i = 0; i < n; ++i) {
    int x, y;
    cin >> x >> y;
    p.emplace_back(x, y);
    g = g + p[i];
  }

  g = g * (1.0 / n);

  if (ok(g, p)) {
    cout << g.x << " " << g.y << endl;
  } else {
    cout << "NA" << endl;
  }

  return EXIT_SUCCESS;
}

Error: 0
50 50


Fixed submission:

#include <cmath>
#include <cstdlib>
#include <iostream>
#include <vector>
using namespace std;

constexpr long double EPS = 1e-7;

struct point {
  long double x, y;
  point(long double x = 0.0, long 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*(long double s) const { return point(x * s, y * s); }
};

long double dot(const point &a, const point &b) {
  return a.x * b.x + a.y * b.y;
}

long double cross(const point &a, const point &b) {
  return a.x * b.y - a.y * b.x;
}

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

int ccw(const point &a, point b, point c) {
  b = b - a;
  c = c - a;
  const long double t = cross(b, c);
  if (t > EPS)
    return 1;
  if (t < -EPS)
    return -1;
  if (dot(b, c) < 0)
    return 2;
  if (norm(b) < norm(c))
    return -2;
  return 0;
}

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

struct line {
  point a, b;
  line(const point &a_, const point &b_) : a(a_), b(b_) {}
};

point crosspoint(const line &a, const line &b) {
  const long double t = cross(a.b - a.a, b.b - b.a);
  if (abs(t) < EPS)
    return a.a;
  return b.a + (b.b - b.a) * cross(a.b - a.a, a.a - b.a) * (1 / t);
}

typedef vector<point> polygon;

long double area(const polygon &p) {
  const int n = p.size();
  if (n < 3)
    return 0.0;

  long double res = cross(p[n - 1], p[0]);
  for (int i = 1; i < n; ++i) {
    res += cross(p[i - 1], p[i]);
  }
  return abs(res) * 0.5;
}

polygon convex_cut(const polygon &p, const line &l) {
  const int n = p.size();
  polygon res;
  for (int i = 0; i < n; ++i) {
    const int next = (i + 1) % n;
    const int tmp = ccw(l.a, l.b, p[i]);
    if (tmp != -1)
      res.emplace_back(p[i]);

    if (tmp * ccw(l.a, l.b, p[next]) < 0) {
      res.emplace_back(crosspoint(l, line(p[i], p[next])));
    }
  }

  return res;
}

bool ok(const point &g, const polygon &p) {
  const long double S_half = area(p) / 2.0;
  for (long double theta = 0; theta < M_PI; theta += 0.01) {
    const long double S =
        area(convex_cut(p, line(g, g + rotate(point(10, 0), theta))));
    if (abs((S_half - S) / S_half) > EPS)
      return false;
  }

  return true;
}

int main() {
  cin.tie(nullptr);
  ios::sync_with_stdio(false);
  cout.precision(5);
  cout.flags(ios::fixed);

  int n;
  cin >> n;

  point g(0, 0);
  polygon p;
  p.reserve(n);
  for (int i = 0; i < n; ++i) {
    int x, y;
    cin >> x >> y;
    p.emplace_back(x, y);
    g = g + p[i];
  }

  g = g * (1.0 / n);
  cerr << g.x << " " << g.y << endl;

  if (ok(g, p)) {
    cout << g.x << " " << g.y << endl;
  } else {
    cout << "NA" << endl;
  }

  return EXIT_SUCCESS;
}