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

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

const double EPS = 1e-8;
enum { OUT, ON, IN };

typedef complex<double> P, point;
typedef vector<P> G, Polygon;
struct L : public vector<P> {
  L(const P &a, const P &b) {
    push_back(a);
    push_back(b);
  }
};
struct C {
  P p;
  double r;
  C(const P &p, double r) : p(p), r(r) {}
  C() {}
};
double cross(const P &a, const P &b) { return imag(conj(a) * b); }
double dot(const P &a, const P &b) { return real(conj(a) * b); }

#define curr(P, i) P[i]
#define next(P, i) P[(i + 1) % P.size()]

int contains(const Polygon &P, const point &p) {
  bool in = false;
  for (int i = 0; i < P.size(); i++) {
    point a = curr(P, i) - p;
    point b = next(P, i) - p;
    if (imag(a) > imag(b))
      swap(a, b);
    if (imag(a) <= 0 && 0 < imag(b))
      if (cross(a, b) < 0)
        in = !in;
    if (cross(a, b) == 0 && dot(a, b) <= 0)
      return ON;
  }

  return in ? IN : OUT;
}
P getPedal(L l, P p) {
  double A;
  if (abs(l[1].real() - l[0].real()) < EPS) {
    return P(l[1].real(), p.imag());
  } else {
    A = (l[1].imag() - l[0].imag()) / (l[1].real() - l[0].real());
  }
  double a = -A;
  double b = 1;
  double c = A * l[0].real() - l[0].imag();
  double t = (a * p.real() + b * p.imag() + c) / (a * a + b * b);
  // cout << p << endl;
  return p - t * P(a, b);
}
vector<P> crossPointCL(const L l, const C c) {
  vector<P> ret;
  P p = getPedal(l, c.p);
  if (abs(p - c.p) > c.r + EPS)
    return ret;
  P e = P((l[1] - l[0]) / abs(l[1] - l[0]));

  double S = sqrt(c.r * c.r - abs(p - c.p) * abs(p - c.p));
  if (c.r * c.r - abs(p - c.p) * abs(p - c.p) < 1e-8)
    S = 0;
  ret.push_back(p + S * e);
  ret.push_back(p - S * e);
  return ret;
}

bool contain(C c, P p) {
  if (p.imag() < EPS)
    return true;
  return abs(c.p - p) < c.r + EPS;
}
double PI = acos(-1);

void vis2(P p) { printf("plot(%.5lf,%.5lf,0)\\n", p.real(), p.imag()); }
int test(vector<G> &g, double t, double r) {
  r -= 1e-4;
  C c = C(P(0, -r + t), r);
  vector<double> chkPoint;
  chkPoint.push_back(0);
  chkPoint.push_back(PI / 2.);
  chkPoint.push_back(3 * PI / 2.);
  chkPoint.push_back(2 * PI / 2.);
  for (int i = 0; i < g.size(); i++) {
    for (int j = 0; j < g[i].size(); j++) {
      auto cp = crossPointCL(L(curr(g[i], j), next(g[i], j)), c);
      for (auto x : cp) {
        x = x - c.p;
        double th = atan2(x.imag(), x.real());
        chkPoint.push_back(th);
        chkPoint.push_back(th + 1e-6);
        chkPoint.push_back(th - 1e-6);
      }
    }
  }
  // cout << "cir(" << c.p.real() << "," << c.p.imag() << "," << r << ")" <<
  // endl;

  for (auto th : chkPoint) {
    P pp = c.p + r * P(cos(th), sin(th));
    if (pp.imag() < EPS)
      continue;
    bool flag = true;
    for (int j = 0; j < g.size(); j++) {
      if (contains(g[j], pp) != OUT) {
        flag = false;
        break;
      }
    }
    // if(flag) vis2(pp);
    if (flag)
      return false;
  }
  return true;
}
void vis(G g) {
  for (int i = 0; i < g.size(); i++) {
    cout << "line(" << curr(g, i).real() << "," << curr(g, i).imag() << ","
         << next(g, i).real() << "," << next(g, i).imag() << ")" << endl;
  }
}
int main() {
  double r;
  int n;
  while (cin >> r >> n && r) {
    vector<G> g;
    // g.push_back({{-1000,-1000},{1000,-1000},{1000,0},{-1000,0}});
    for (int i = 0; i < n; i++) {
      double xl, xr, h;
      cin >> xl >> xr >> h;
      g.push_back({{xl, 0}, {xr, 0}, {xr, h}, {xl, h}});
      // vis(g[i]);
    }

    double L = 0, R = 1000;
    for (int i = 0; i < 64; i++) {
      double M = (L + R) / 2.;
      if (!test(g, M, r)) {
        R = M;
      } else {
        L = M;
      }
    }
    printf("%.10lf\\n", L);
  }
}

Error: TLE

Fixed submission:

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

const double EPS = 1e-8;
enum { OUT, ON, IN };

typedef complex<double> P, point;
typedef vector<P> G, Polygon;
struct L : public vector<P> {
  L(const P &a, const P &b) {
    push_back(a);
    push_back(b);
  }
};
struct C {
  P p;
  double r;
  C(const P &p, double r) : p(p), r(r) {}
  C() {}
};
double cross(const P &a, const P &b) { return imag(conj(a) * b); }
double dot(const P &a, const P &b) { return real(conj(a) * b); }

#define curr(P, i) P[i]
#define next(P, i) P[(i + 1) % P.size()]

int contains(const Polygon &P, const point &p) {
  bool in = false;
  for (int i = 0; i < P.size(); i++) {
    point a = curr(P, i) - p;
    point b = next(P, i) - p;
    if (imag(a) > imag(b))
      swap(a, b);
    if (imag(a) <= 0 && 0 < imag(b))
      if (cross(a, b) < 0)
        in = !in;
    if (cross(a, b) == 0 && dot(a, b) <= 0)
      return ON;
  }

  return in ? IN : OUT;
}

P e[100010];
int D = 50000;
double PI = acos(-1);
int test(vector<G> &g, double t, double r) {
  C c = C(P(0, -r + t), r);
  vector<P> chkPoint;

  for (int i = 0; i < D; i++) {
    chkPoint.push_back(c.p + r * e[i]);
  }
  for (auto p : chkPoint) {
    if (p.imag() < EPS)
      continue;
    bool flag = true;
    for (int j = 0; j < g.size(); j++) {
      if (contains(g[j], p) != OUT) {
        flag = false;
        break;
      }
    }
    if (flag)
      return false;
  }
  return true;
}
int main() {
  for (int i = 0; i < D; i++) {
    e[i] = P(cos(i * 2. * PI / D), sin(i * 2. * PI / D));
  }
  double r;
  int n;
  while (cin >> r >> n && r) {
    vector<G> g;
    g.push_back({{-1000, -1000}, {1000, -1000}, {1000, 0}, {-1000, 0}});
    for (int i = 0; i < n; i++) {
      double xl, xr, h;
      cin >> xl >> xr >> h;
      g.push_back({{xl - 1e-7, -1e-7},
                   {xr + 1e-7, -1e-7},
                   {xr + 1e-7, h + 1e-7},
                   {xl - 1e-7, h + 1e-7}});
    }
    double L = 0, R = 1000;
    for (int i = 0; i < 64; i++) {
      double M = (L + R) / 2.;
      if (!test(g, M, r)) {
        R = M;
      } else {
        L = M;
      }
    }
    printf("%.10lf\\n", L);
  }
}