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

#include <algorithm>
#include <cassert>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
#include <set>
#include <vector>

using namespace std;
typedef long long ll;

typedef double R;
typedef complex<R> P;

const R EPS = 1e-7;
const R PI = acos((R)(-1));

/*
 -1 -> neg
  0 -> near 0
  1 -> pos
  */
int sgn(R a) {
  if (a < -EPS)
    return -1;
  if (a > EPS)
    return 1;
  return 0;
}

int sgn(R a, R b) { return sgn(b - a); }

bool near(P a, P b) { return !sgn(abs(a - b)); }

bool lessP(const P &l, const P &r) {
  if (sgn(l.real(), r.real()))
    return l.real() < r.real();
  if (sgn(l.imag(), r.imag()))
    return l.imag() < r.imag();
  return false;
}

R cross(P a, P b) { return a.real() * b.imag() - a.imag() * b.real(); }
R dot(P a, P b) { return a.real() * b.real() + a.imag() * b.imag(); }

/* 1->cclock
  -1->clock
   0->on
   2->back
  -2->front
  */
int ccw(P a, P b, P c) {
  assert(!near(a, b));
  if (near(a, c) || near(b, c))
    return 0;
  int s = sgn(cross(b - a, c - a));
  if (s)
    return s;
  if (dot(b - a, c - a) < 0)
    return 2;
  if (dot(a - b, c - b) < 0)
    return -2;
  return 0;
}

R sacos(R d) {
  d = max<R>(-1, d);
  d = min<R>(1, d);
  return acos(d);
}

struct L {
  P x, y;
  L(){};
  L(P x, P y) : x(x), y(y){};
};

P vec(const L &l) { return l.y - l.x; }

R abs(const L &l) { return abs(vec(l)); }

int crossLL(const L &l, const L &m, P &r) {
  L mm = L(m.x - l.x, m.y - l.x);
  mm.x *= polar<R>(1.0, -arg(vec(l)));
  mm.y *= polar<R>(1.0, -arg(vec(l)));
  if (sgn(vec(mm).imag()) == 0) {
    if (sgn(mm.x.imag()) == 0)
      return -1;
    return 0;
  }
  r = mm.x - vec(mm) * (mm.x.imag() / vec(mm).imag());
  r *= polar<R>(1.0, arg(vec(l)));
  r += l.x;
  return 1;
}

int crossSS(const L &l, const L &m, P &r) {
  int u = crossLL(l, m, r);
  if (u == 0)
    return 0;
  if (u == -1) {
    int x = ccw(l.x, l.y, m.x);
    int y = ccw(l.x, l.y, m.y);
    if (x == 0) {
      r = m.x;
      return -1;
    }
    if (y == 0) {
      r = m.y;
      return -1;
    }
    if (x == y)
      return 0;
    r = l.x;
    return -1;
  }
  if (ccw(l.x, l.y, r) == 0 && ccw(m.x, m.y, r) == 0)
    return 1;
  return 0;
}

R distLP(const L &l, const P &p) {
  return abs(cross(vec(l), p - l.x) / abs(vec(l)));
}

struct C {
  P p;
  R r;
  C() {}
  C(P p, R r) : p(p), r(r) {}
};

// need Intersect/distLP
int crossLC(const L &l, const C &c, L &r) {
  R u = distLP(l, c.p);
  int si = sgn(u - c.r);
  if (si == 1)
    return 0;
  P v = (l.y - l.x) / abs(l) * P(0, -1); // l?????´???????????????????????????
  v *= u;
  if (ccw(l.x, l.y, c.p) < 0)
    v *= -1;
  // v?????????????????????l?????¨??????????????????????????????
  if (si == 0) {
    r.x = r.y = c.p + v;
    return 1;
  }
  r.x = c.p + v + polar<R>(sqrt(c.r * c.r - u * u), arg(vec(l)));
  r.y = c.p + v - polar<R>(sqrt(c.r * c.r - u * u), arg(vec(l)));
  return 2;
}

// return number of cross point
int crossCC(const C &c, const C &d, L &l) {
  if (near(c.p, d.p) && !sgn(c.r, d.r)) {
    l.x = l.y = c.p + P(c.r, 0);
    return -1;
  }
  R di = abs(c.p - d.p);
  if (sgn(c.r + d.r, di) == 1)
    return 0;
  if (sgn(di, abs(c.r - d.r)) == 1)
    return 0;
  R bth = arg(d.p - c.p);
  R th = sacos((c.r * c.r + di * di - d.r * d.r) / (2 * c.r * di));
  l.x = c.p + polar<R>(c.r, bth + th);
  l.y = c.p + polar<R>(c.r, bth - th);
  if (sgn(th) == 0)
    return 1;
  return 2;
}

typedef vector<P> Pol;

P cu(const Pol &p, int i) {
  int s = p.size();
  return p[(i % s + s) % s];
};

// 0:P is out 1:P is on line 2:P is in
int contains(const Pol &pol, P p) {
  int in = -1;
  for (int i = 0; i < (int)pol.size(); i++) {
    P a = cu(pol, i) - p, b = cu(pol, i + 1) - p;
    if (ccw(a, b, P(0, 0)) == 0)
      return 1;
    if (imag(a) > imag(b))
      swap(a, b);
    if (imag(a) <= 0 && 0 < imag(b)) {
      if (cross(a, b) < 0)
        in *= -1;
    }
  }
  return in + 1;
}

Pol l2rect(const L &l, R r) {
  P v = vec(l) * P(0, 1) / abs(vec(l)) * r;
  Pol p;
  p.push_back(l.x + v);
  p.push_back(l.x - v);
  p.push_back(l.y - v);
  p.push_back(l.y + v);
  return p;
}

Pol po;

bool solve(R md) {
  int n = po.size();
  vector<L> lv;
  vector<Pol> pov;
  vector<C> cv;
  for (int i = 0; i < n; i++) {
    cv.push_back(C(po[i], md));
    pov.push_back(l2rect(L(po[i], po[(i + 1) % n]), md));
  }
  for (Pol &pp : pov) {
    lv.push_back(L(cu(pp, 3), cu(pp, 0)));
    for (int i = 0; i < 4; i++) {
    }
  }
  vector<P> pv;
  for (int i = 0; i < n; i++) {
    for (int j = i + 1; j < n; j++) {
      P pp;
      if (crossSS(lv[i], lv[j], pp)) {
        pv.push_back(pp);
      }
    }
  }
  for (P &p : pv) {
    if (contains(po, p) == 0)
      continue;
    bool f = true;
    for (Pol &po : pov) {
      if (contains(po, p) == 2) {
        f = false;
        break;
      }
    }
    if (!f)
      continue;
    for (C &c : cv) {
      if (sgn(abs(c.p - p), c.r) == 1) {
        f = false;
        break;
      }
    }
    if (!f)
      continue;
    // printf("%.lf", md);
    // cout << p << endl;
    return true;
  }
  return false;
}

int main() {
  while (true) {
    int n;
    cin >> n;
    if (!n)
      break;
    po.clear();
    for (int i = 0; i < n; i++) {
      R x, y;
      cin >> x >> y;
      po.push_back(P(x, y));
    }
    R l = 0, r = 1e5;
    for (int i = 0; i < 50; i++) {
      R md = (l + r) / 2;
      if (solve(md)) {
        l = md;
      } else {
        r = md;
      }
    }
    printf("%.20lf\\n", l);
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cassert>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
#include <set>
#include <vector>

using namespace std;
typedef long long ll;

typedef double R;
typedef complex<R> P;

const R EPS = 1e-7;
const R PI = acos((R)(-1));

/*
 -1 -> neg
  0 -> near 0
  1 -> pos
  */
int sgn(R a) {
  if (a < -EPS)
    return -1;
  if (a > EPS)
    return 1;
  return 0;
}

int sgn(R a, R b) { return sgn(b - a); }

bool near(P a, P b) { return !sgn(abs(a - b)); }

bool lessP(const P &l, const P &r) {
  if (sgn(l.real(), r.real()))
    return l.real() < r.real();
  if (sgn(l.imag(), r.imag()))
    return l.imag() < r.imag();
  return false;
}

R cross(P a, P b) { return a.real() * b.imag() - a.imag() * b.real(); }
R dot(P a, P b) { return a.real() * b.real() + a.imag() * b.imag(); }

/* 1->cclock
  -1->clock
   0->on
   2->back
  -2->front
  */
int ccw(P a, P b, P c) {
  assert(!near(a, b));
  if (near(a, c) || near(b, c))
    return 0;
  int s = sgn(cross(b - a, c - a));
  if (s)
    return s;
  if (dot(b - a, c - a) < 0)
    return 2;
  if (dot(a - b, c - b) < 0)
    return -2;
  return 0;
}

R sacos(R d) {
  d = max<R>(-1, d);
  d = min<R>(1, d);
  return acos(d);
}

struct L {
  P x, y;
  L(){};
  L(P x, P y) : x(x), y(y){};
};

P vec(const L &l) { return l.y - l.x; }

R abs(const L &l) { return abs(vec(l)); }

int crossLL(const L &l, const L &m, P &r) {
  L mm = L(m.x - l.x, m.y - l.x);
  mm.x *= polar<R>(1.0, -arg(vec(l)));
  mm.y *= polar<R>(1.0, -arg(vec(l)));
  if (sgn(vec(mm).imag()) == 0) {
    if (sgn(mm.x.imag()) == 0)
      return -1;
    return 0;
  }
  r = mm.x - vec(mm) * (mm.x.imag() / vec(mm).imag());
  r *= polar<R>(1.0, arg(vec(l)));
  r += l.x;
  return 1;
}

int crossSS(const L &l, const L &m, P &r) {
  int u = crossLL(l, m, r);
  if (u == 0)
    return 0;
  if (u == -1) {
    int x = ccw(l.x, l.y, m.x);
    int y = ccw(l.x, l.y, m.y);
    if (x == 0) {
      r = m.x;
      return -1;
    }
    if (y == 0) {
      r = m.y;
      return -1;
    }
    if (x == y)
      return 0;
    r = l.x;
    return -1;
  }
  if (ccw(l.x, l.y, r) == 0 && ccw(m.x, m.y, r) == 0)
    return 1;
  return 0;
}

R distLP(const L &l, const P &p) {
  return abs(cross(vec(l), p - l.x) / abs(vec(l)));
}

struct C {
  P p;
  R r;
  C() {}
  C(P p, R r) : p(p), r(r) {}
};

// need Intersect/distLP
int crossLC(const L &l, const C &c, L &r) {
  R u = distLP(l, c.p);
  int si = sgn(u - c.r);
  if (si == 1)
    return 0;
  P v = (l.y - l.x) / abs(l) * P(0, -1); // l?????´???????????????????????????
  v *= u;
  if (ccw(l.x, l.y, c.p) < 0)
    v *= -1;
  // v?????????????????????l?????¨??????????????????????????????
  if (si == 0) {
    r.x = r.y = c.p + v;
    return 1;
  }
  r.x = c.p + v + polar<R>(sqrt(c.r * c.r - u * u), arg(vec(l)));
  r.y = c.p + v - polar<R>(sqrt(c.r * c.r - u * u), arg(vec(l)));
  return 2;
}

// return number of cross point
int crossCC(const C &c, const C &d, L &l) {
  if (near(c.p, d.p) && !sgn(c.r, d.r)) {
    l.x = l.y = c.p + P(c.r, 0);
    return -1;
  }
  R di = abs(c.p - d.p);
  if (sgn(c.r + d.r, di) == 1)
    return 0;
  if (sgn(di, abs(c.r - d.r)) == 1)
    return 0;
  R bth = arg(d.p - c.p);
  R th = sacos((c.r * c.r + di * di - d.r * d.r) / (2 * c.r * di));
  l.x = c.p + polar<R>(c.r, bth + th);
  l.y = c.p + polar<R>(c.r, bth - th);
  if (sgn(th) == 0)
    return 1;
  return 2;
}

typedef vector<P> Pol;

P cu(const Pol &p, int i) {
  int s = p.size();
  return p[(i % s + s) % s];
};

// 0:P is out 1:P is on line 2:P is in
int contains(const Pol &pol, P p) {
  int in = -1;
  for (int i = 0; i < (int)pol.size(); i++) {
    P a = cu(pol, i) - p, b = cu(pol, i + 1) - p;
    if (ccw(a, b, P(0, 0)) == 0)
      return 1;
    if (imag(a) > imag(b))
      swap(a, b);
    if (imag(a) <= 0 && 0 < imag(b)) {
      if (cross(a, b) < 0)
        in *= -1;
    }
  }
  return in + 1;
}

Pol l2rect(const L &l, R r) {
  P v = vec(l) * P(0, 1) / abs(vec(l)) * r;
  Pol p;
  p.push_back(l.x + v);
  p.push_back(l.x - v);
  p.push_back(l.y - v);
  p.push_back(l.y + v);
  return p;
}

Pol po;

bool solve(R md) {
  int n = po.size();
  vector<L> lv;
  vector<Pol> pov;
  vector<C> cv;
  for (int i = 0; i < n; i++) {
    cv.push_back(C(po[i], md));
    pov.push_back(l2rect(L(po[i], po[(i + 1) % n]), md));
  }
  for (Pol &pp : pov) {
    for (int i = 0; i < 4; i++) {
      lv.push_back(L(cu(pp, i), cu(pp, i + 1)));
    }
  }
  vector<P> pv;
  for (int i = 0; i < n * 4; i++) {
    for (int j = i + 1; j < n * 4; j++) {
      P pp;
      if (crossSS(lv[i], lv[j], pp)) {
        pv.push_back(pp);
      }
    }
  }
  for (P &p : pv) {
    if (contains(po, p) == 0)
      continue;
    bool f = true;
    for (Pol &po : pov) {
      if (contains(po, p) == 2) {
        f = false;
        break;
      }
    }
    if (!f)
      continue;
    for (C &c : cv) {
      if (sgn(abs(c.p - p), c.r) == 1) {
        f = false;
        break;
      }
    }
    if (!f)
      continue;
    // printf("%.lf", md);
    // cout << p << endl;
    return true;
  }
  return false;
}

int main() {
  while (true) {
    int n;
    cin >> n;
    if (!n)
      break;
    po.clear();
    for (int i = 0; i < n; i++) {
      R x, y;
      cin >> x >> y;
      po.push_back(P(x, y));
    }
    R l = 0, r = 1e5;
    for (int i = 0; i < 50; i++) {
      R md = (l + r) / 2;
      if (solve(md)) {
        l = md;
      } else {
        r = md;
      }
    }
    printf("%.20lf\\n", l);
  }
  return 0;
}