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

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

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

const double EPS = 1e-8;

namespace std {
bool operator<(const P &a, const P &b) {
  return fabs(real(a) - real(b)) < EPS ? imag(a) < imag(b) : real(a) < real(b);
}
bool operator==(const P &a, const P &b) {
  return fabs(real(a) - real(b)) < EPS && fabs(imag(a) - imag(b)) < EPS;
}
} // namespace std

struct Circle {
  P c;
  double r;
  Circle(P c = P(0, 0), double r = 0) : c(c), r(r) {}
};

double dot(P a, P b) { return real(conj(a) * b); }
double cross(P a, P b) { return imag(conj(a) * b); }

P proj(P p, L l) {
  return l.first + dot(p - l.first, l.second - l.first) /
                       norm(l.second - l.first) * (l.second - l.first);
}

P rotate(P p, double rad) {
  double x = real(p) * cos(rad) - imag(p) * sin(rad);
  double y = real(p) * sin(rad) + imag(p) * cos(rad);
  return P(x, y);
}

vector<P> getIntersectCL(Circle c, L l) {
  vector<P> res;
  P h = proj(c.c, l);
  double d = abs(c.c - h);
  if (d > c.r + EPS)
    ;
  else if (d > c.r - EPS)
    res.push_back(h);
  else {
    P v = l.second - l.first;
    v = (sqrt(c.r * c.r - d * d) / abs(v)) * v;
    res.push_back(h + v);
    res.push_back(h - v);
  }
  return res;
}

vector<P> getIntersectCC(Circle c1, Circle c2) {
  vector<P> res;
  double r1 = c1.r, r2 = c2.r, d;
  P p1 = c1.c, p2 = c2.c;
  d = abs(p1 - p2);

  if (d < EPS && abs(r1 - r2) < EPS)
    return res; //????????¨?????????????????´???????????????????????????????????????
  if (r1 + r2 < d - EPS || d + EPS < abs(r1 - r2))
    return res; //???????????????

  double a = (r1 * r1 - r2 * r2 + d * d) / (2 * d);
  double h = sqrt(max(r1 * r1 - a * a, 0.0));
  P tmp1 = p1 + a / d * (p2 - p1);
  P tmp2 = h / d * (p2 - p1);

  if (abs(tmp2) < EPS)
    res.push_back(tmp1);
  else {
    res.push_back(P(real(tmp1) - imag(tmp2), imag(tmp1) + real(tmp2)));
    res.push_back(P(real(tmp1) + imag(tmp2), imag(tmp1) - real(tmp2)));
  }
  return res;
}

vector<L> tangentCC(Circle c1, Circle c2) {
  vector<L> res;
  double d = abs(c1.c - c2.c);
  if (d < EPS)
    return res;

  // ?????\\???
  if (c1.r + c2.r < d - EPS) {
    double t = acos((c1.r + c2.r) / d);
    res.push_back(L(c1.c + rotate(c1.r / d * (c2.c - c1.c), t),
                    c2.c + rotate(c2.r / d * (c1.c - c2.c), t)));
    res.push_back(L(c1.c + rotate(c1.r / d * (c2.c - c1.c), -t),
                    c2.c + rotate(c2.r / d * (c1.c - c2.c), -t)));
  } else if (c1.r + c2.r < d + EPS) {
    P p = c1.c + c1.r / d * (c2.c - c1.c);
    res.push_back(L(p, p + rotate(c2.c - c1.c, M_PI / 2.0)));
  }

  // ?????\\???
  if (abs(c1.r - c2.r) < d - EPS) {
    double t1 = acos((c1.r - c2.r) / d), t2 = M_PI - t1;
    res.push_back(L(c1.c + rotate(c1.r / d * (c2.c - c1.c), t1),
                    c2.c + rotate(c2.r / d * (c1.c - c2.c), -t2)));
    res.push_back(L(c1.c + rotate(c1.r / d * (c2.c - c1.c), -t1),
                    c2.c + rotate(c2.r / d * (c1.c - c2.c), t2)));
  } else if (abs(c1.r - c2.r) < d + EPS) {
    P p = c1.c + c1.r / d * (c2.c - c1.c);
    res.push_back(L(p, p + rotate(c2.c - c1.c, M_PI / 2)));
  }

  return res;
}

int n;
vector<Circle> v, w;

int calc(L l) {
  int sum = 0;
  for (int k = 0; k < n; k++) {
    if (getIntersectCL(v[k], l).size() <= 1 &&
        getIntersectCL(w[k], l).size() >= 1) {
      sum++;
    }
  }
  return sum;
}

int solve() {
  int ans = 1;
  vector<P> pv;

  for (int i = 0; i < n; i++) {
    for (int j = i + 1; j < n; j++) {
      vector<P> res = getIntersectCC(w[i], w[j]);
      for (int k = 0; k < res.size(); k++) {
        pv.push_back(res[k]);
      }

      vector<L> resl = tangentCC(w[i], w[j]);
      for (int k = 0; k < resl.size(); k++) {
        ans = max(ans, calc(resl[k]));
        // pv.push_back(resl[k].first);
        // pv.push_back(resl[k].second);
      }

      resl = tangentCC(v[i], v[j]);
      for (int k = 0; k < resl.size(); k++) {
        ans = max(ans, calc(resl[k]));
        // pv.push_back(resl[k].first);
        // pv.push_back(resl[k].second);
      }
    }
  }

  // pv.erase(unique(pv.begin(), pv.end()), pv.end());

  for (int i = 0; i < pv.size(); i++) {
    for (int j = i + 1; j < pv.size(); j++) {
      ans = max(ans, calc(L(pv[i], pv[j])));
    }
  }

  return ans;
}

int main() {
  while (cin >> n && n) {
    v.clear();
    w.clear();
    for (int i = 0; i < n; i++) {
      double x, y, r, m;
      cin >> x >> y >> r >> m;
      v.push_back(Circle(P(x, y), r));
      w.push_back(Circle(P(x, y), r + m));
    }
    cout << solve() << endl;
  }
}

Error: TLE

Fixed submission:

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

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

const double EPS = 1e-8;

namespace std {
bool operator==(const P &a, const P &b) {
  return fabs(real(a) - real(b)) < EPS && fabs(imag(a) - imag(b)) < EPS;
}
} // namespace std

struct Circle {
  P c;
  double r;
  Circle(P c = P(0, 0), double r = 0) : c(c), r(r) {}
};

double dot(P a, P b) { return real(conj(a) * b); }
double cross(P a, P b) { return imag(conj(a) * b); }

P proj(P p, L l) {
  return l.first + dot(p - l.first, l.second - l.first) /
                       norm(l.second - l.first) * (l.second - l.first);
}

P rotate(P p, double rad) {
  double x = real(p) * cos(rad) - imag(p) * sin(rad);
  double y = real(p) * sin(rad) + imag(p) * cos(rad);
  return P(x, y);
}

vector<P> getIntersectCL(Circle c, L l) {
  vector<P> res;
  P h = proj(c.c, l);
  double d = abs(c.c - h);
  if (d > c.r + EPS)
    ;
  else if (d > c.r - EPS)
    res.push_back(h);
  else {
    P v = l.second - l.first;
    v = (sqrt(c.r * c.r - d * d) / abs(v)) * v;
    res.push_back(h + v);
    res.push_back(h - v);
  }
  return res;
}

vector<P> getIntersectCC(Circle c1, Circle c2) {
  vector<P> res;
  double r1 = c1.r, r2 = c2.r, d;
  P p1 = c1.c, p2 = c2.c;
  d = abs(p1 - p2);

  if (d < EPS && abs(r1 - r2) < EPS)
    return res; //????????¨?????????????????´???????????????????????????????????????
  if (r1 + r2 < d - EPS || d + EPS < abs(r1 - r2))
    return res; //???????????????

  double a = (r1 * r1 - r2 * r2 + d * d) / (2 * d);
  double h = sqrt(max(r1 * r1 - a * a, 0.0));
  P tmp1 = p1 + a / d * (p2 - p1);
  P tmp2 = h / d * (p2 - p1);

  if (abs(tmp2) < EPS)
    res.push_back(tmp1);
  else {
    res.push_back(P(real(tmp1) - imag(tmp2), imag(tmp1) + real(tmp2)));
    res.push_back(P(real(tmp1) + imag(tmp2), imag(tmp1) - real(tmp2)));
  }
  return res;
}

vector<L> tangentCC(Circle c1, Circle c2) {
  vector<L> res;
  double d = abs(c1.c - c2.c);
  if (d < EPS)
    return res;

  // ?????\\???
  if (c1.r + c2.r < d - EPS) {
    double t = acos((c1.r + c2.r) / d);
    res.push_back(L(c1.c + rotate(c1.r / d * (c2.c - c1.c), t),
                    c2.c + rotate(c2.r / d * (c1.c - c2.c), t)));
    res.push_back(L(c1.c + rotate(c1.r / d * (c2.c - c1.c), -t),
                    c2.c + rotate(c2.r / d * (c1.c - c2.c), -t)));
  } else if (c1.r + c2.r < d + EPS) {
    P p = c1.c + c1.r / d * (c2.c - c1.c);
    res.push_back(L(p, p + rotate(c2.c - c1.c, M_PI / 2.0)));
  }

  // ?????\\???
  if (abs(c1.r - c2.r) < d - EPS) {
    double t1 = acos((c1.r - c2.r) / d), t2 = M_PI - t1;
    res.push_back(L(c1.c + rotate(c1.r / d * (c2.c - c1.c), t1),
                    c2.c + rotate(c2.r / d * (c1.c - c2.c), -t2)));
    res.push_back(L(c1.c + rotate(c1.r / d * (c2.c - c1.c), -t1),
                    c2.c + rotate(c2.r / d * (c1.c - c2.c), t2)));
  } else if (abs(c1.r - c2.r) < d + EPS) {
    P p = c1.c + c1.r / d * (c2.c - c1.c);
    res.push_back(L(p, p + rotate(c2.c - c1.c, M_PI / 2)));
  }

  return res;
}

int n;
vector<Circle> v, w;

int solve() {
  int ans = 1;
  vector<P> pv;

  for (int i = 0; i < n; i++) {
    for (int j = i + 1; j < n; j++) {
      vector<P> res = getIntersectCC(w[i], w[j]);
      for (int k = 0; k < res.size(); k++) {
        pv.push_back(res[k]);
      }

      vector<L> resl = tangentCC(w[i], w[j]);
      for (int k = 0; k < resl.size(); k++) {
        pv.push_back(resl[k].first);
        pv.push_back(resl[k].second);
      }
      /*
      resl = tangentCC(v[i],v[j]);
      for(int k=0;k<resl.size();k++){
        pv.push_back(resl[k].first);
        pv.push_back(resl[k].second);
        }*/
    }
  }

  pv.erase(unique(pv.begin(), pv.end()), pv.end());

  for (int i = 0; i < pv.size(); i++) {
    for (int j = i + 1; j < pv.size(); j++) {
      L l = L(pv[i], pv[j]);
      int sum = 0;
      for (int k = 0; k < n; k++) {
        if (getIntersectCL(v[k], l).size() <= 1 &&
            getIntersectCL(w[k], l).size() >= 1) {
          sum++;
        }
      }
      ans = max(ans, sum);
    }
  }

  return ans;
}

int main() {
  while (cin >> n && n) {
    v.clear();
    w.clear();
    for (int i = 0; i < n; i++) {
      double x, y, r, m;
      cin >> x >> y >> r >> m;
      v.push_back(Circle(P(x, y), r));
      w.push_back(Circle(P(x, y), r + m));
    }
    cout << solve() << endl;
  }
}