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

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

typedef long double elem;
typedef complex<elem> point, vec;
typedef pair<point, point> seg, line;
const elem eps = 1e-8;
enum CCW { BACK = 0x01, FRONT = 0x02, RIGHT = 0x04, LEFT = 0x08, OVER = 0x10 };

bool eq(elem a, elem b) { return abs(b - a) < eps; }
vec uvec(const vec &v) { return v / abs(v); }
vec nml(vec a) { return a * vec(0, 1); }
vec unml(vec a) { return uvec(nml(a)); }

elem dot(const point &a, const point &b) {
  return a.real() * b.real() + a.imag() * b.imag();
}

elem cross(const point &a, const point &b) {
  return a.real() * b.imag() - a.imag() * b.real();
}

inline int ccw(const point &a, point b, point x) {
  b -= a;
  x -= a;
  if (eq(cross(b, x), 0) && dot(b, x) < 0)
    return BACK;
  if (eq(cross(b, x), 0) && abs(b) < abs(x))
    return FRONT;
  if (eq(cross(b, x), 0))
    return OVER;
  if (cross(b, x) > 0)
    return LEFT;
  return RIGHT;
}

elem dist_l(const line &l, const point &x) {
  return abs(cross(l.second - l.first, x - l.first)) / abs(l.second - l.first);
}

elem dist_seg(const seg &s, const point &x) {
  if (dot(s.second - s.first, x - s.first) < 0)
    return abs(x - s.first);
  if (dot(s.first - s.second, x - s.second) < 0)
    return abs(x - s.second);
  return dist_l(s, x);
}

bool prll(const line &a, const line &b) {
  return eq(cross(a.second - a.first, b.second - b.first), 0);
}

bool intersectedLL(const line &a, const line &b) {
  return !eq(cross(a.second - a.first, b.second - b.first), 0.0);
}

point intersectionSS(const seg &a, const seg &b) {
  elem d1 = dist_l(b, a.first);
  elem d2 = dist_l(b, a.second);
  return a.first + (d1 / (d1 + d2)) * (a.second - a.first);
}

point intersectionLL(const line &a, const line &b) {
  vec va = a.second - a.first;
  vec vb = b.second - b.first;
  return a.first + va * (cross(vb, b.first - a.first) / cross(vb, va));
}

bool intersectionLL(const line &a, const line &b, point &ret) {
  return intersectedLL(a, b) ? ret = intersectionLL(a, b), true : false;
}

bool intersectionLS(const line &l, const seg &s, point &ret) {
  point tmp;
  return intersectionLL(l, s, tmp)
             ? (ccw(s.first, s.second, tmp) & OVER ? ret = tmp, true : false)
             : false;
}

bool cmpXy(const point &a, const point &b) {
  if (eq(a.real(), b.real()))
    return a.imag() < b.imag();
  if (a.real() < b.real())
    return true;
  return false;
}

void andrewConvexHull(const vector<point> &Q, vector<point> &CH) {
  vector<point> T = Q;
  if (Q.size() < 3) {
    CH = Q;
    return;
  }
  int n = T.size(), k = 0;
  sort(T.begin(), T.end(), cmpXy);
  CH.resize(2 * n);
  for (int i = 0; i < n; CH[k++] = T[i++]) {
    while (k >= 2 && ccw(CH[k - 2], CH[k - 1], T[i]) & (RIGHT | BACK))
      --k;
  }
  for (int i = n - 2, t = k + 1; i >= 0; CH[k++] = T[i--]) {
    while (k >= t && ccw(CH[k - 2], CH[k - 1], T[i]) & (RIGHT | BACK))
      --k;
  }
  CH.resize(k - 1);
}

bool regularConvex(vector<point> &vp) {
  vector<point> ret;
  for (int i = 0; i < (int)vp.size(); ++i) {
    for (int j = i + 1; j < (int)vp.size(); ++j) {
      if (eq(abs(vp[i] - vp[j]), 0)) {
        vp.erase(vp.begin() + j);
      }
    }
  }
  andrewConvexHull(vp, ret);
  vp = ret;
}

bool convexCut(const vector<point> &vp, line l, vector<point> &left) {
  vector<point> tmp;
  for (int i = 0; i < (int)vp.size(); ++i) {
    if (ccw(l.first, l.second, vp[i]) == LEFT) {
      tmp.push_back(vp[i]);
    }
  }
  for (int i = 0; i < (int)vp.size(); ++i) {
    point is;
    seg s(vp[i], vp[(i + 1) % vp.size()]);
    if (intersectionLS(l, s, is)) {
      tmp.push_back(is);
    }
  }
  regularConvex(tmp);
  left = tmp;
  return true;
}

elem area(const vector<point> &vp) {
  elem ret = 0;
  for (int i = 0; i < (int)vp.size(); ++i) {
    ret += cross(vp[i], vp[(i + 1) % vp.size()]);
  }
  return abs(ret / 2);
}

int main() {
  int n;
  while (cin >> n && n) {
    vector<point> vp;
    elem res = 1e20;
    point c;
    for (int i = 0; i < n; ++i) {
      elem x, y;
      cin >> x >> y;
      x *= 10;
      y *= 10;
      vp.push_back(point(x, y));
    }

    elem r = 1e7;
    elem l = 0;
    int cnt = 0;
    vector<point> L;
    while (cnt++ < 200) {
      elem m = (l + r) / 2.;

      L = vp;
      for (int i = 0; i < n; ++i) {
        line a(vp[i], vp[(i + 1) % n]);
        point b = m * unml(a.second - a.first);

        line la(b + a.first, b + a.second);
        // cout << a.first << ' ' << a.second << ' ' << la.first << ' ' <<
        // la.second << endl;
        vector<point> newL;
        convexCut(L, la, newL);
        L = newL;
      }

      /*
      cout << m << ' ' << " Size : " << L.size() << endl;
      for(int i = 0; i < (int)L.size(); ++i){
        cout << L[i] << ' ';
      }
      cout << endl;
      */

      if (L.size() < 3) {
        r = m;
      } else {
        l = m;
      }
    }

    for (int i = 0; i < n; ++i) {
      res = min(res, dist_seg(seg(vp[i], vp[(i + 1) % n]), L[0]));
    }
    cout << fixed << setprecision(6) << res / 10 << endl;
  }
  return 0;
}

Error: TLE

Fixed submission:

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

typedef complex<double> point, vec;
typedef pair<point, point> seg, line;
const double eps = 1e-9;
enum CCW { BACK = 0x01, FRONT = 0x02, RIGHT = 0x04, LEFT = 0x08, OVER = 0x10 };

bool eq(double a, double b) { return abs(b - a) < eps; }

vec uvec(const vec &v) { return v / abs(v); }
double dot(const point &a, const point &b) {
  return a.real() * b.real() + a.imag() * b.imag();
}
double cross(const point &a, const point &b) {
  return a.real() * b.imag() - a.imag() * b.real();
}

inline int ccw(const point &a, point b, point x) {
  b -= a;
  x -= a;
  if (eq(cross(b, x), 0) && dot(b, x) < 0)
    return BACK;
  if (eq(cross(b, x), 0) && abs(b) < abs(x))
    return FRONT;
  if (eq(cross(b, x), 0))
    return OVER;
  if (cross(b, x) > 0)
    return LEFT;
  return RIGHT;
}

bool prll(const line &a, const line &b) {
  return eq(cross(a.second - a.first, b.second - b.first), 0);
}

point intersectionLL(const line &a, const line &b) {
  vec va = a.second - a.first;
  vec vb = b.second - b.first;
  return a.first + va * (cross(vb, b.first - a.first) / cross(vb, va));
}

double dist_l(const line &l, const point &x) {
  return abs(cross(l.second - l.first, x - l.first)) / abs(l.second - l.first);
}

double dist_seg(const seg &s, const point &x) {
  if (dot(s.second - s.first, x - s.first) < 0)
    return abs(x - s.first);
  if (dot(s.first - s.second, x - s.second) < 0)
    return abs(x - s.second);
  return dist_l(s, x);
}

bool insimple(const point &x, const vector<point> &p) {
  int cnt = 0;
  int n = p.size();
  for (int i = 0; i < n; ++i) {
    point a = p[i] - x, b = p[(i + 1) % n] - x;
    if (b.imag() > a.imag())
      swap(a, b);
    int cw = ccw(a, b, point(0, 0));
    if (cw == LEFT && 0 <= a.imag() && b.imag() < 0)
      ++cnt;
    if (cw == OVER)
      return true;
  }
  if (cnt & 1)
    return true;
  return false;
}

int main() {
  int n;
  while (cin >> n && n) {
    vector<point> vp;
    double res = 0;
    for (int i = 0; i < n; ++i) {
      double x, y;
      cin >> x >> y;
      vp.push_back(point(x, y));
    }
    for (int i = 0; i < n; ++i) {
      for (int j = 0; j < n; ++j) {
        line a(vp[i], vp[(i + 1) % vp.size()]);
        line b(vp[j], vp[(j - 1 + vp.size()) % vp.size()]);
        bool prl = prll(a, b);
        if (prl)
          continue;
        vec uva = uvec(a.second - a.first);
        vec uvb = uvec(b.second - b.first);
        vec v = uvec((uva + uvb));
        point cr = intersectionLL(a, b);

        double r = 1e20;
        double l = 0;
        int cnt = 0;
        double radi;
        while (cnt++ < 200) {
          double m = (r + l) / 2.;
          point c = m * v + cr;
          bool ng = false;

          radi = dist_l(a, c);
          if (!insimple(c, vp)) {
            r = m;
            continue;
          }

          for (int k = 0; k < n; ++k) {
            seg s(vp[k], vp[(k + 1) % vp.size()]);
            if (radi > dist_seg(s, c) + eps) {
              ng = true;
              break;
            }
          }

          if (ng) {
            r = m;
          } else {
            l = m;
          }
        }
        res = max(res, radi);
      }
    }
    cout << fixed << setprecision(12) << res << endl;
  }
  return 0;
}