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

#include <bits/stdc++.h>
using namespace std;
const double EPS = 1e-8;
const double INF = 1e12;
#define X real()
#define Y imag()
#define curr(P, i) P[i]
#define next(P, i) P[(i + 1) % P.size()]
#define prev(P, i) P[(i + P.size() - 1) % P.size()]
#define diff(P, i) (next(P, i) - curr(P, i))
#define EQ(a, b) (abs((a) - (b)) < EPS)

typedef complex<double> P;
namespace std {
bool operator<(const P &a, const P &b) {
  return real(a) != real(b) ? real(a) < real(b) : imag(a) < imag(b);
}
bool operator==(const P &a, const P &b) { return abs(a - b) < EPS; }
} // namespace std
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);
}

struct L : public vector<P> { //??????
  L(const P &a, const P &b) {
    push_back(a);
    push_back(b);
  }
};

typedef vector<P> G;
struct C { //???
  P p;
  double r;
  C(const P &p, double r) : p(p), r(r) {}
};

int ccw(P a, P b, P c) { //??????????????????
  b -= a;
  c -= a;
  if (cross(b, c) > 0)
    return +1; // counter clockwise
  if (cross(b, c) < 0)
    return -1; // clockwise
  if (dot(b, c) < 0)
    return +2; // c--a--b on line
  if (norm(b) < norm(c))
    return -2; // a--b--c on line
  return 0;
}

// p??????l?????????????????????????????????
P projection(const L &l, const P &p) {
  double t = dot(p - l[0], l[0] - l[1]) / norm(l[0] - l[1]);
  return l[0] + t * (l[0] - l[1]);
}
// l???????§°?????¨????????????p??¨???????§°?????????????????????
P reflection(const L &l, const P &p) { return p + 2. * (projection(l, p) - p); }

bool intersectLL(const L &l, const L &m) {
  // non-parallel || sameline
  return abs(cross(l[1] - l[0], m[1] - m[0])) > EPS ||
         abs(cross(l[1] - l[0], m[0] - l[0])) < EPS;
}
bool intersectLS(const L &l, const L &s) {
  // s[0] is left of l,s[1] is right of l
  return cross(l[1] - l[0], s[0] - l[0]) * cross(l[1] - l[0], s[1] - l[0]) <
         EPS;
}
bool intersectSS(const L &s, const L &t) {
  return ccw(s[0], s[1], t[0]) * ccw(s[0], s[1], t[1]) <= 0 &&
         ccw(t[0], t[1], s[0]) * ccw(t[0], t[1], s[1]) <= 0;
}
bool intersectLP(const L &l, const P &p) {
  return abs(cross(l[1] - p, l[0] - p)) < EPS;
}
bool intersectSP(const L &s, const P &p) {
  return abs(s[0] - p) + abs(s[1] - p) - abs(s[1] - s[0]) <
         EPS; // triangle inequality
}

double distancePP(const P &a, const P &b) { return abs(a - b); }
double distanceSP(const L &s, const P &p) {
  const P r = projection(s, p);
  if (intersectSP(s, r))
    return abs(r - p);
  return min(abs(s[0] - p), abs(s[1] - p));
}
double distanceLP(const L &l, const P &p) { return abs(p - projection(l, p)); }
double distanceLL(const L &l, const L &m) {
  return intersectLL(l, m) ? 0 : distanceLP(l, m[0]);
}
double distanceLS(const L &l, const L &s) {
  if (intersectLS(l, s))
    return 0;
  return min(distanceLP(l, s[0]), distanceLP(l, s[1]));
}
double distanceSS(const L &s, const L &t) {
  if (intersectSS(s, t))
    return 0;
  return min(min(distanceSP(s, t[0]), distanceSP(s, t[1])),
             min(distanceSP(t, s[0]), distanceSP(t, s[1])));
}

// ??´???????????????
bool orthogonalLL(const L &l1, const L &l2) {
  return (dot(l1[0] - l1[1], l2[0] - l2[1]) <= EPS &&
          dot(l1[0] - l1[1], l2[0] - l2[1]) >= -EPS);
}
// ??????????????????
bool parallelLL(const L &l1, const L &l2) {
  return (cross(l1[0] - l1[1], l2[0] - l2[1]) <= EPS &&
          cross(l1[0] - l1[1], l2[0] - l2[1]) >= -EPS);
}

// ??????
P crosspointLL(const L &l, const L &m) {
  double A = cross(l[1] - l[0], m[1] - m[0]);
  double B = cross(l[1] - l[0], l[1] - m[0]);
  if (abs(A) < EPS && abs(B) < EPS)
    return m[0]; // same line
  if (abs(A) < EPS)
    assert(false); // !!!PRECONDITION NOT SATISFIED!!!
  return m[0] + B / A * (m[1] - m[0]);
}
vector<P> crosspointCL(const C &c, const L &l) {
  vector<P> res;
  double d = distanceLP(l, c.p);
  if (d < c.r + EPS) {
    double len = (d > c.r) ? 0.0 : sqrt(c.r * c.r - d * d);
    P nor = (l[0] - l[1]) / abs(l[0] - l[1]);
    res.push_back(projection(l, c.p) + len * nor);
    res.push_back(projection(l, c.p) - len * nor);
  }
  return res;
}
vector<P> crosspointCS(const C &c, const L &l) {
  vector<P> v = crosspointCL(c, l), res;
  for (int k = 0; k < v.size(); k++)
    if (ccw(l[0], v[k], l[1]) == -2)
      res.push_back(v[k]);
  return res;
}
vector<P> crosspointCC(const C &c1, const C &c2) {
  vector<P> res;
  double d = abs(c1.p - c2.p);
  double rc = (d * d + c1.r * c1.r - c2.r * c2.r) / (2 * d);
  double dfr = c1.r * c1.r - rc * rc;
  if (EQ(dfr, 0.0))
    dfr = 0.0;
  else if (dfr < 0.0)
    return res;
  double rs = sqrt(dfr);

  P diff = (c2.p - c1.p) / d;
  res.push_back(c1.p + diff * P(rc, rs));
  res.push_back(c1.p + diff * P(rc, -rs));
  return res;
}

//-1 : ???????????????
// 0 : ??\\??????
// 1 : ???????????§????????????
// 2 : ???????????§????????????
int intersectSC(const L &s, const C &c) {
  int ins = 0;
  for (int i = 0; i < 2; i++) {
    if (abs(s[i] - c.p) < c.r)
      ins++;
    else if (EQ(abs(s[i] - c.p), c.r))
      return 0;
  }
  if (ins == 2)
    return -1;
  if (ins == 1)
    return 1;
  double d = distanceLP(s, c.p);
  if (d - c.r > EPS)
    return -1;
  P nor = (s[0] - s[1]) * P(0, 1);
  if (ccw(c.p, c.p + nor, s[0]) * ccw(c.p, c.p + nor, s[1]) < 0)
    return 2;
  return -1;
}

int main(void) {
  while (true) {
    int r, n;
    cin >> r >> n;
    if (r == 0 && n == 0)
      return 0;
    vector<int> xl(n), xr(n), h(n);

    vector<int> height(100);
    const int z = 20;
    for (int i = 0; i < n; i++) {
      cin >> xl[i] >> xr[i] >> h[i];
      for (int j = xl[i]; j < xr[i]; j++) {
        height[j + z] = max(height[j + z], h[i]);
      }
    }

    vector<L> lines;
    for (int i = -20; i <= 20; i++) {
      P p1(i, height[i + z]);
      P p2(i + 1, height[i + z]);
      lines.emplace_back(p1, p2);
      // cerr << i << "~" << i+1 << ":" << height[i+z] << endl;
    }

    bool ok = false;
    for (double t = 0; t <= 41; t += 0.001) {
      C taiyou(P(0, -r + t), r);
      for (int i = 0; i < lines.size(); i++) {
        if (intersectSC(lines[i], taiyou) >= 1) {
          // for(double dt=0;dt<=0.001;dt+=0.0001){
          // C taiyou2(P(0,-r+t-dt),r);
          // if(intersectSC(lines[i],taiyou2) < 1){
          cout << fixed << setprecision(10) << t - EPS << endl;
          // break;
          // }
          // }
          ok = true;
          break;
        }
      }
      if (ok)
        break;
    }
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;
const double EPS = 1e-8;
const double INF = 1e12;
#define X real()
#define Y imag()
#define curr(P, i) P[i]
#define next(P, i) P[(i + 1) % P.size()]
#define prev(P, i) P[(i + P.size() - 1) % P.size()]
#define diff(P, i) (next(P, i) - curr(P, i))
#define EQ(a, b) (abs((a) - (b)) < EPS)

typedef complex<double> P;
namespace std {
bool operator<(const P &a, const P &b) {
  return real(a) != real(b) ? real(a) < real(b) : imag(a) < imag(b);
}
bool operator==(const P &a, const P &b) { return abs(a - b) < EPS; }
} // namespace std
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);
}

struct L : public vector<P> { //??????
  L(const P &a, const P &b) {
    push_back(a);
    push_back(b);
  }
};

typedef vector<P> G;
struct C { //???
  P p;
  double r;
  C(const P &p, double r) : p(p), r(r) {}
};

int ccw(P a, P b, P c) { //??????????????????
  b -= a;
  c -= a;
  if (cross(b, c) > 0)
    return +1; // counter clockwise
  if (cross(b, c) < 0)
    return -1; // clockwise
  if (dot(b, c) < 0)
    return +2; // c--a--b on line
  if (norm(b) < norm(c))
    return -2; // a--b--c on line
  return 0;
}

// p??????l?????????????????????????????????
P projection(const L &l, const P &p) {
  double t = dot(p - l[0], l[0] - l[1]) / norm(l[0] - l[1]);
  return l[0] + t * (l[0] - l[1]);
}
// l???????§°?????¨????????????p??¨???????§°?????????????????????
P reflection(const L &l, const P &p) { return p + 2. * (projection(l, p) - p); }

bool intersectLL(const L &l, const L &m) {
  // non-parallel || sameline
  return abs(cross(l[1] - l[0], m[1] - m[0])) > EPS ||
         abs(cross(l[1] - l[0], m[0] - l[0])) < EPS;
}
bool intersectLS(const L &l, const L &s) {
  // s[0] is left of l,s[1] is right of l
  return cross(l[1] - l[0], s[0] - l[0]) * cross(l[1] - l[0], s[1] - l[0]) <
         EPS;
}
bool intersectSS(const L &s, const L &t) {
  return ccw(s[0], s[1], t[0]) * ccw(s[0], s[1], t[1]) <= 0 &&
         ccw(t[0], t[1], s[0]) * ccw(t[0], t[1], s[1]) <= 0;
}
bool intersectLP(const L &l, const P &p) {
  return abs(cross(l[1] - p, l[0] - p)) < EPS;
}
bool intersectSP(const L &s, const P &p) {
  return abs(s[0] - p) + abs(s[1] - p) - abs(s[1] - s[0]) <
         EPS; // triangle inequality
}

double distancePP(const P &a, const P &b) { return abs(a - b); }
double distanceSP(const L &s, const P &p) {
  const P r = projection(s, p);
  if (intersectSP(s, r))
    return abs(r - p);
  return min(abs(s[0] - p), abs(s[1] - p));
}
double distanceLP(const L &l, const P &p) { return abs(p - projection(l, p)); }
double distanceLL(const L &l, const L &m) {
  return intersectLL(l, m) ? 0 : distanceLP(l, m[0]);
}
double distanceLS(const L &l, const L &s) {
  if (intersectLS(l, s))
    return 0;
  return min(distanceLP(l, s[0]), distanceLP(l, s[1]));
}
double distanceSS(const L &s, const L &t) {
  if (intersectSS(s, t))
    return 0;
  return min(min(distanceSP(s, t[0]), distanceSP(s, t[1])),
             min(distanceSP(t, s[0]), distanceSP(t, s[1])));
}

// ??´???????????????
bool orthogonalLL(const L &l1, const L &l2) {
  return (dot(l1[0] - l1[1], l2[0] - l2[1]) <= EPS &&
          dot(l1[0] - l1[1], l2[0] - l2[1]) >= -EPS);
}
// ??????????????????
bool parallelLL(const L &l1, const L &l2) {
  return (cross(l1[0] - l1[1], l2[0] - l2[1]) <= EPS &&
          cross(l1[0] - l1[1], l2[0] - l2[1]) >= -EPS);
}

// ??????
P crosspointLL(const L &l, const L &m) {
  double A = cross(l[1] - l[0], m[1] - m[0]);
  double B = cross(l[1] - l[0], l[1] - m[0]);
  if (abs(A) < EPS && abs(B) < EPS)
    return m[0]; // same line
  if (abs(A) < EPS)
    assert(false); // !!!PRECONDITION NOT SATISFIED!!!
  return m[0] + B / A * (m[1] - m[0]);
}
vector<P> crosspointCL(const C &c, const L &l) {
  vector<P> res;
  double d = distanceLP(l, c.p);
  if (d < c.r + EPS) {
    double len = (d > c.r) ? 0.0 : sqrt(c.r * c.r - d * d);
    P nor = (l[0] - l[1]) / abs(l[0] - l[1]);
    res.push_back(projection(l, c.p) + len * nor);
    res.push_back(projection(l, c.p) - len * nor);
  }
  return res;
}
vector<P> crosspointCS(const C &c, const L &l) {
  vector<P> v = crosspointCL(c, l), res;
  for (int k = 0; k < v.size(); k++)
    if (ccw(l[0], v[k], l[1]) == -2)
      res.push_back(v[k]);
  return res;
}
vector<P> crosspointCC(const C &c1, const C &c2) {
  vector<P> res;
  double d = abs(c1.p - c2.p);
  double rc = (d * d + c1.r * c1.r - c2.r * c2.r) / (2 * d);
  double dfr = c1.r * c1.r - rc * rc;
  if (EQ(dfr, 0.0))
    dfr = 0.0;
  else if (dfr < 0.0)
    return res;
  double rs = sqrt(dfr);

  P diff = (c2.p - c1.p) / d;
  res.push_back(c1.p + diff * P(rc, rs));
  res.push_back(c1.p + diff * P(rc, -rs));
  return res;
}

//-1 : ???????????????
// 0 : ??\\??????
// 1 : ???????????§????????????
// 2 : ???????????§????????????
int intersectSC(const L &s, const C &c) {
  int ins = 0;
  for (int i = 0; i < 2; i++) {
    if (abs(s[i] - c.p) < c.r)
      ins++;
    else if (EQ(abs(s[i] - c.p), c.r))
      return 0;
  }
  if (ins == 2)
    return -1;
  if (ins == 1)
    return 1;
  double d = distanceLP(s, c.p);
  if (d - c.r > EPS)
    return -1;
  P nor = (s[0] - s[1]) * P(0, 1);
  if (ccw(c.p, c.p + nor, s[0]) * ccw(c.p, c.p + nor, s[1]) < 0)
    return 2;
  return -1;
}

int main(void) {
  while (true) {
    int r, n;
    cin >> r >> n;
    if (r == 0 && n == 0)
      return 0;
    vector<int> xl(n), xr(n), h(n);

    vector<int> height(100);
    const int z = 20;
    for (int i = 0; i < n; i++) {
      cin >> xl[i] >> xr[i] >> h[i];
      for (int j = xl[i]; j < xr[i]; j++) {
        height[j + z] = max(height[j + z], h[i]);
      }
    }

    vector<L> lines;
    for (int i = -20; i <= 20; i++) {
      P p1(i, height[i + z]);
      P p2(i + 1, height[i + z]);
      lines.emplace_back(p1, p2);
      // cerr << i << "~" << i+1 << ":" << height[i+z] << endl;
    }

    bool ok = false;
    for (double t = 0; t <= 41; t += 0.0001) {
      C taiyou(P(0, -r + t), r);
      for (int i = 0; i < lines.size(); i++) {
        if (intersectSC(lines[i], taiyou) >= 1) {
          for (double dt = 0; dt <= 0.0001; dt += 0.00001) {
            C taiyou2(P(0, -r + t - dt), r);
            if (intersectSC(lines[i], taiyou2) < 1) {
              cout << fixed << setprecision(10) << t - dt + 0.00001 << endl;
              break;
            }
          }
          ok = true;
          break;
        }
      }
      if (ok)
        break;
    }
  }
  return 0;
}