Problem p01556 (C++) — buggy submission, verdict: Time Limit Exceeded

#include <bits/stdc++.h>
using namespace std;

typedef complex<long double> P;
typedef pair<P, P> L;

const long double INF = 1e+9;
const long double EPS = 1e-5;

bool equal(long double a, long double b) { return fabs(a - b) < EPS; }
long double dot(P a, P b) { return real(conj(a) * b); }
long double cross(P a, P b) { return imag(conj(a) * b); }
int ccw(P a, P b, P c) {
  b -= a;
  c -= a;
  if (cross(b, c) > EPS)
    return 1;
  if (cross(b, c) < -EPS)
    return -1;
  if (dot(b, c) < -EPS)
    return 2;
  if (norm(b) < norm(c))
    return -2;
  return 0;
}
P crossPoint(L l, L m) {
  long double A = cross(l.second - l.first, m.second - m.first);
  long double B = cross(l.second - l.first, l.second - m.first);
  if (fabs(A) < EPS && fabs(B) < EPS)
    return m.first;
  else if (fabs(A) >= EPS)
    return m.first + B / A * (m.second - m.first);
}
vector<P> convex_cut(vector<P> G, L l) {
  vector<P> ans;
  for (int i = 0; i < G.size(); i++) {
    P A = G[i];
    P B = G[(i + 1) % G.size()];
    if (ccw(l.first, l.second, A) != -1)
      ans.push_back(A);
    if (ccw(l.first, l.second, A) * ccw(l.first, l.second, B) < 0)
      ans.push_back(crossPoint(L(A, B), l));
  }
  return ans;
}
long double area(vector<P> v) {
  long double sum = 0.0;
  int n = v.size();
  for (int i = 0; i < n; i++)
    sum += (real(v[i]) - real(v[(i + 1) % n])) *
           (imag(v[i]) + imag(v[(i + 1) % n]));
  return fabs(sum) / 2;
};
bool equal(P a, P b) {
  return equal(a.real(), b.real()) && equal(a.imag(), b.imag());
}

int n;
vector<P> v;

long double binary_search(bool is_h) {
  L l;
  long double le = -INF, ri = INF, mid;
  vector<P> cut_v;

  while (ri - le > EPS / 1000.0) {
    mid = (ri + le) / 2.0;
    if (is_h)
      l = L(P(-INF, mid), P(INF, mid));
    else
      l = L(P(mid, INF), P(mid, -INF));
    cut_v = convex_cut(v, l);
    if (area(v) > area(cut_v) * 2.0)
      ri = mid;
    else
      le = mid;
  }

  return (ri + le) / 2.0;
}

P solve() {
  P res = P(binary_search(false), binary_search(true));
  bool f = true;

  if (n % 2 == 1)
    f = false;
  else {
    for (int i = 0; i < n / 2; i++) {
      if (!equal(v[i] - res, res - v[i + n / 2])) {
        f = false;
        break;
      }
    }
  }

  if (f)
    return res;
  else
    return P(INF, INF);
}

int main() {
  long double x, y;
  while (cin >> n) {
    v.clear();
    for (int i = 0; i < n; i++) {
      cin >> x >> y;
      v.push_back(P(x, y));
    }
    P res = solve();
    if (equal(res, P(INF, INF)))
      cout << "NA" << endl;
    else
      printf("%.6Lf %.6Lf\\n", res.real(), res.imag());
  }
}

Error: TLE

Fixed submission:

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

typedef complex<double> P;
typedef pair<P, P> L;
const double EPS = 1e-4;
const double INF = 1000000001.0;

double dot(P a, P b) { return real(conj(a) * b); }
double cross(P a, P b) { return imag(conj(a) * b); }
int ccw(P a, P b, P c) {
  b -= a;
  c -= a;
  if (cross(b, c) > EPS)
    return 1;
  if (cross(b, c) < -EPS)
    return -1;
  if (dot(b, c) < -EPS)
    return 2;
  if (norm(b) < norm(c))
    return -2;
  return 0;
}
bool isInter(L s1, L s2) {
  return (ccw(s1.first, s1.second, s2.first) *
                  ccw(s1.first, s1.second, s2.second) <=
              0 &&
          ccw(s2.first, s2.second, s1.first) *
                  ccw(s2.first, s2.second, s1.second) <=
              0);
}
P crossPoint(L l, L m) {
  double A = cross(l.second - l.first, m.second - m.first);
  double B = cross(l.second - l.first, l.second - m.first);
  if (fabs(A) < EPS && fabs(B) < EPS)
    return m.first;
  else if (fabs(A) >= EPS)
    return m.first + B / A * (m.second - m.first);
}
double area(vector<P> v) {
  double sum = 0.0;
  int n = v.size();
  for (int i = 0; i < n; i++)
    sum += (real(v[i]) - real(v[(i + 1) % n])) *
           (imag(v[i]) + imag(v[(i + 1) % n]));
  return fabs(sum) / 2.0;
}
vector<P> convex_cut(vector<P> G, L l) {
  vector<P> ans;
  for (int i = 0; i < G.size(); i++) {
    P A = G[i];
    P B = G[(i + 1) % G.size()];
    if (ccw(l.first, l.second, A) != -1)
      ans.push_back(A);
    if (ccw(l.first, l.second, A) * ccw(l.first, l.second, B) < 0)
      ans.push_back(crossPoint(L(A, B), l));
  }
  return ans;
}
bool equal(double a, double b) { return (fabs(a - b) < EPS); }
P rotate(P p, double theta) {
  theta = theta * M_PI / 180.0;
  double x = real(p) * cos(theta) - imag(p) * sin(theta);
  double y = real(p) * sin(theta) + imag(p) * cos(theta);
  return P(x, y);
}

int main() {
  int n;
  while (cin >> n) {
    vector<P> v;
    double minx = INF, miny = INF, maxx = -INF, maxy = -INF;
    for (int i = 0; i < n; i++) {
      double a, b;
      cin >> a >> b;
      v.push_back(P(a, b));
      minx = min(minx, a);
      maxx = max(maxx, a);
      miny = min(miny, b);
      maxy = max(maxy, b);
    }

    double l = miny;
    double r = maxy;
    double all = area(v);
    L yoko, tate;
    while (1) {
      //	 cout << l << ' ' << r << endl;
      double mid = (l + r) / 2.0;
      double half = area(convex_cut(v, L(P(-INF, mid), P(INF, mid))));
      if (equal(half * 2.0, all)) {
        yoko = L(P(-INF, mid), P(INF, mid));
        break;
      } else if (half * 2.0 > all)
        l = mid;
      else
        r = mid;
    }

    l = minx;
    r = maxx;
    while (1) {
      double mid = (l + r) / 2.0;
      double half = area(convex_cut(v, L(P(mid, INF), P(mid, -INF))));
      if (equal(half * 2.0, all)) {
        tate = L(P(mid, -INF), P(mid, INF));
        break;
      } else if (half * 2.0 > all)
        l = mid;
      else
        r = mid;
    }

    P ans = crossPoint(yoko, tate);
    bool f = true;
    //      printf("%.5f %.5f  ",real(ans),imag(ans));

    for (double i = 0.0; i < 180.0; i += 1.0) {
      L line = L(rotate(P(-INF, 0.0), i) + ans, rotate(P(INF, 0.0), i) + ans);
      double half = area(convex_cut(v, line));
      if (!equal(half * 2.0, all)) {
        //	    printf("%.5f %.5f ",half*2.0, all);
        f = false;
        break;
      }
    }
    if (f)
      printf("%.5f %.5f\\n", real(ans), imag(ans));
    else
      cout << "NA" << endl;
  }
}