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

#include <algorithm>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdio>
#include <iostream>
#include <map>
#include <set>
#include <sstream>
#include <string>
#include <vector>
using namespace std;

typedef long long LL;
typedef vector<int> vi;
typedef vector<string> vs;
typedef vector<vector<int>> vii;
typedef vector<vector<string>> vss;
typedef pair<int, int> pii;
#define x first
#define y second
#define INF 0x7fffffff
// #define INFLL 0x7fffffffffffffff
#define INFLL LLONG_MAX
#define SIZE(v) int((v).size())
#define ALL(v) (v).begin(), (v).end()
#define FOR(i, x) for (int i = 0; i < x; i++)
#define FORic(i, y, x) for (int i = y; i <= x; i++)
#define FORdc(i, y, x) for (int i = y; i >= x; i--)
#define FILL(a, v) memset(a, v, sizeof(a))
#define PI 3.14159265358979323846

const double EPS = 1e-7;
typedef complex<double> P; /* _ */
typedef vector<P> G;       /* ½p` */
struct L {                 /* üª */
  double angle;            // deleteSameLineðgpµÈ¢Àèsv
  P p, q;
  L(P p, P q) : p(p), q(q), angle(arg(q - p)) {}
  bool operator<(const L &l) const { return angle < l.angle; }
};
typedef pair<P, double> C; /* ~ */

// complexÉå¬ÖWªKvÈê
namespace std {
bool operator<(const P &a, const P &b) {
  return make_pair(real(a), imag(a)) < make_pair(real(b), imag(b));
}
} // namespace std

// àÏEOÏEpx
double dot(P a, P b) { return real(conj(a) * b); }
double cross(P a, P b) { return imag(conj(a) * b); }
double angle(P a, P b) { return arg(conj(a) * b); }

// _pÆ´_Ì£yÌñæzðßé
// iüÍp1-p2ðøÉæêÎ2_ÔÌ£yÌñæzÆÈéj
double pLen2(P p) { return real(p) * real(p) + imag(p) * imag(p); }

// ½Ë(distSPÅgp)
P proj(L l, P p) {
  double t = dot(p - l.p, l.p - l.q) / sqrt(pLen2(l.p - l.q));
  return l.p + t * (l.p - l.q);
}

// ¼ülÆüªsªð··é©ð»è·é
bool lsIntersect(L l, L s) {
  return abs(cross(l.q - l.p, s.p - l.p) * cross(l.q - l.p, s.q - l.p)) < EPS;
}

// üªaÆüªbªð··é©ð»è·é
bool ssIntersect(L a, L b) {
  if (abs(imag((a.q - a.p) / (b.q - b.p))) < EPS)
    return false;
  return cross(a.q - a.p, b.p - a.p) * cross(a.q - a.p, b.q - a.p) < 0 &&
         cross(b.q - b.p, a.p - b.p) * cross(b.q - b.p, a.q - b.p) < 0;
}

// _pª¼ülãÉ¶Ý·é©ð»è
bool lpIntersect(L l, P p) { return abs(imag((p - l.p) / (l.q - l.p))) < EPS; }

// _pªüªlãÉ¶Ý·é©ð»è·éi¸x¤j
bool spIntersect(L l, P p) {
  // return abs( abs(l.p-p)+abs(l.q-p)-abs(l.q-l.p) ) < EPS; //
  // ¸xðCÉµÈ¢Èç±êH
  if (lpIntersect(l, p)) {
    if ((real(l.p) - real(p)) * (real(l.q) - real(p)) <= 0) {
      if ((imag(l.p) - imag(p)) * (imag(l.q) - imag(p)) <= 0) {
        return true;
      }
    }
  }
  return false;
}

// üªaÆüªbÌð_ðvZ·éDæÉð·»èªK{D
P ssCrosspoint(L a, L b) {
  double A = cross(a.q - a.p, b.q - b.p);
  double B = cross(a.q - a.p, a.q - b.p);
  return b.p + B / A * (b.q - b.p);
}

// ¼üaÆ¼übª¯êÌàÌ©ð»è·é
bool sameLine(L a, L b) { return lpIntersect(a, b.p) && lpIntersect(a, b.q); }

// üªlÆ_pÌ£ðßé
double distLP(L l, P p) {
  return abs(cross(l.q - l.p, p - l.p)) / abs(l.q - l.p);
}

// ¼üÆ¼üÌ£ðßéiÀsÌj
double distLL(L l, L m) { return sameLine(l, m) ? 0.0 : distLP(l, m.p); }

// ¼ülÆüªsÌ£ðßé
double distLS(L l, L s) {
  if (lsIntersect(l, s))
    return 0.0;
  return min(distLP(l, s.p), distLP(l, s.q));
}

// üªsÆ_pÌ£ðßé
double distSP(L s, P p) {
  P r = proj(s, p);
  if (spIntersect(s, r))
    return abs(r - p);
  return min(abs(s.p - p), abs(s.q - p));
}

// üªsÆüªtÌ£ðßé
double distSS(L s, L t) {
  if (ssIntersect(s, t))
    return 0;
  return min(min(distSP(s, t.p), distSP(s, t.q)),
             min(distSP(t, s.p), distSP(t, s.q)));
}

// üªaÆüªbªI[o[bvµÄ¢é©ð»è·é
bool ssOverlap(L a, L b) {
  if (spIntersect(a, b.p) && lpIntersect(a, b.q))
    return true;
  if (spIntersect(a, b.q) && lpIntersect(a, b.p))
    return true;
  if (spIntersect(b, a.p) && lpIntersect(b, a.q))
    return true;
  if (spIntersect(b, a.q) && lpIntersect(b, a.p))
    return true;
  return false;
}

// ¤ÊÚüðresÉÇÁ·é
void getCommonTangent(vector<L> &res, C c1, C c2) {
  if (c1.second > c2.second)
    swap(c1, c2);
  P dir = c1.first - c2.first;
  double dist = abs(c1.first - c2.first);
  dir = dir / dist * c2.second;
  if (dist + c1.second < c2.second - EPS)
    return; // ¬~ªå~Éàï³êÄ¢é

  for (int sgn = -1; sgn <= 1; sgn += 2) {
    double cs = (c2.second + sgn * c1.second) / dist;
    P d = P(cs, sqrt(1 - cs * cs));
    res.push_back(L(c2.first + dir * d, c2.first + dir * d * P(1, 1)));
    if (imag(d) > EPS)
      res.push_back(
          L(c2.first + dir * conj(d), c2.first + dir * conj(d) * P(1, 1)));
    if (dist + EPS < c1.second + c2.second)
      break;
  }
}

// ½p`gÌÊÏðßé
double polygonArea(G g) {
  double res = 0.0;
  for (int i = 0; i < g.size(); i++)
    res += cross(g[i], g[(i + 1) % g.size()]);
  return abs(0.5 * res);
}

// _pª½p`gÌàÉ é©Ç¤©ð»è·é
bool contains(G g, P p) {
  bool in = false;
  for (int i = 0; i < g.size(); i++) {
    P a(g[i] - p), b(g[(i + 1) % g.size()] - p);
    if (imag(a) > imag(b))
      swap(a, b);
    if (imag(a) <= 0 && 0 < imag(b))
      if (cross(a, b) < 0)
        in = !in;
    if (abs(cross(a, b)) < EPS && dot(a, b) < EPS)
      return true; // üãÉpª¶Ý
  }
  return in;
}

// ¼üÌWresÅd¡·é¼üðíµCresðXV·é
// px\\[gðÀ·êÎ¬»}êéª¸s·éEEE
void deleteSameLine(vector<L> &res) {
  int n = res.size();
  for (int i = 0; i < n; i++) {
    if (imag(res[i].p) > imag(res[i].q)) {
      P temp = res[i].p;
      res[i].p = res[i].q;
      res[i].q = temp;
    }
  }
  sort(res.begin(), res.end());
  for (int i = 0; i < n; i++) {
    vector<L>::iterator it = res.begin() + i + 1;
    while (it < res.end()) {
      if (abs(res[i].angle - (*it).angle) > EPS) {
        break;
      }
      if (sameLine(
              res[i],
              (*it))) { /* ±±ðÏ¦êÎpªø­ */
        it = res.erase(it);
        n--;
      } else {
        it++;
      }
    }
  }
}

int main() {
  int n;
  while (cin >> n) {
    if (!n)
      break;
    vi x, y, r, m;
    FOR(i, n) {
      int tx, ty, tr, tm;
      cin >> tx >> ty >> tr >> tm;
      x.push_back(tx);
      y.push_back(ty);
      r.push_back(tr);
      m.push_back(tm);
    }
    if (n == 1) {
      cout << 1 << endl;
      continue;
    }
    vector<L> all;
    FORic(i, 0, n - 2) {
      FORic(j, i + 1, n - 1) {
        getCommonTangent(all, C(P(x[i], y[i]), r[i]), C(P(x[j], y[j]), r[j]));
        getCommonTangent(all, C(P(x[i], y[i]), r[i] + m[i]),
                         C(P(x[j], y[j]), r[j]));
        getCommonTangent(all, C(P(x[i], y[i]), r[i]),
                         C(P(x[j], y[j]), r[j] + m[j]));
        getCommonTangent(all, C(P(x[i], y[i]), r[i] + m[i]),
                         C(P(x[j], y[j]), r[j] + m[j]));
      }
    }
    deleteSameLine(all);
    int ans = 0;
    FOR(i, SIZE(all)) {
      int count = 0;
      FOR(j, n) {
        double d = distLP(all[i], P(x[j], y[j]));
        if (r[j] < d + EPS && d - EPS < r[j] + m[j])
          count++;
      }
      ans = max(ans, count);
    }
    cout << ans << endl;
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdio>
#include <iostream>
#include <map>
#include <set>
#include <sstream>
#include <string>
#include <vector>
using namespace std;

typedef long long LL;
typedef vector<int> vi;
typedef vector<string> vs;
typedef vector<vector<int>> vii;
typedef vector<vector<string>> vss;
typedef pair<int, int> pii;
#define x first
#define y second
#define INF 0x7fffffff
// #define INFLL 0x7fffffffffffffff
#define INFLL LLONG_MAX
#define SIZE(v) int((v).size())
#define ALL(v) (v).begin(), (v).end()
#define FOR(i, x) for (int i = 0; i < x; i++)
#define FORic(i, y, x) for (int i = y; i <= x; i++)
#define FORdc(i, y, x) for (int i = y; i >= x; i--)
#define FILL(a, v) memset(a, v, sizeof(a))
#define PI 3.14159265358979323846

const double EPS = 1e-7;
typedef complex<double> P; /* _ */
typedef vector<P> G;       /* ½p` */
struct L {
  P p, q;
  L(P p, P q) : p(p), q(q) {}
};                         /* üª */
typedef pair<P, double> C; /* ~ */

// complexÉå¬ÖWªKvÈê
namespace std {
bool operator<(const P &a, const P &b) {
  return make_pair(real(a), imag(a)) < make_pair(real(b), imag(b));
}
} // namespace std

// àÏEOÏEpx
double dot(P a, P b) { return real(conj(a) * b); }
double cross(P a, P b) { return imag(conj(a) * b); }
double angle(P a, P b) { return arg(conj(a) * b); }

// _pÆ´_Ì£yÌñæzðßé
// iüÍp1-p2ðøÉæêÎ2_ÔÌ£yÌñæzÆÈéj
double pLen2(P p) { return real(p) * real(p) + imag(p) * imag(p); }

// ½Ë(distSPÅgp)
P proj(L l, P p) {
  double t = dot(p - l.p, l.p - l.q) / sqrt(pLen2(l.p - l.q));
  return l.p + t * (l.p - l.q);
}

// ¼ülÆüªsªð··é©ð»è·é
bool lsIntersect(L l, L s) {
  return abs(cross(l.q - l.p, s.p - l.p) * cross(l.q - l.p, s.q - l.p)) < EPS;
}

// üªaÆüªbªð··é©ð»è·é
bool ssIntersect(L a, L b) {
  if (abs(imag((a.q - a.p) / (b.q - b.p))) < EPS)
    return false;
  return cross(a.q - a.p, b.p - a.p) * cross(a.q - a.p, b.q - a.p) < 0 &&
         cross(b.q - b.p, a.p - b.p) * cross(b.q - b.p, a.q - b.p) < 0;
}

// _pª¼ülãÉ¶Ý·é©ð»è
bool lpIntersect(L l, P p) { return abs(imag((p - l.p) / (l.q - l.p))) < EPS; }

// _pªüªlãÉ¶Ý·é©ð»è·éi¸x¤j
bool spIntersect(L l, P p) {
  // return abs( abs(l.p-p)+abs(l.q-p)-abs(l.q-l.p) ) < EPS; //
  // ¸xðCÉµÈ¢Èç±êH
  if (lpIntersect(l, p)) {
    if ((real(l.p) - real(p)) * (real(l.q) - real(p)) <= 0) {
      if ((imag(l.p) - imag(p)) * (imag(l.q) - imag(p)) <= 0) {
        return true;
      }
    }
  }
  return false;
}

// üªaÆüªbÌð_ðvZ·éDæÉð·»èªK{D
P ssCrosspoint(L a, L b) {
  double A = cross(a.q - a.p, b.q - b.p);
  double B = cross(a.q - a.p, a.q - b.p);
  return b.p + B / A * (b.q - b.p);
}

// ¼üaÆ¼übª¯êÌàÌ©ð»è·é
bool sameLine(L a, L b) { return lpIntersect(a, b.p) && lpIntersect(a, b.q); }

// üªlÆ_pÌ£ðßé
double distLP(L l, P p) {
  return abs(cross(l.q - l.p, p - l.p)) / abs(l.q - l.p);
}

// ¼üÆ¼üÌ£ðßéiÀsÌj
double distLL(L l, L m) { return sameLine(l, m) ? 0.0 : distLP(l, m.p); }

// ¼ülÆüªsÌ£ðßé
double distLS(L l, L s) {
  if (lsIntersect(l, s))
    return 0.0;
  return min(distLP(l, s.p), distLP(l, s.q));
}

// üªsÆ_pÌ£ðßé
double distSP(L s, P p) {
  P r = proj(s, p);
  if (spIntersect(s, r))
    return abs(r - p);
  return min(abs(s.p - p), abs(s.q - p));
}

// üªsÆüªtÌ£ðßé
double distSS(L s, L t) {
  if (ssIntersect(s, t))
    return 0;
  return min(min(distSP(s, t.p), distSP(s, t.q)),
             min(distSP(t, s.p), distSP(t, s.q)));
}

// üªaÆüªbªI[o[bvµÄ¢é©ð»è·é
bool ssOverlap(L a, L b) {
  if (spIntersect(a, b.p) && lpIntersect(a, b.q))
    return true;
  if (spIntersect(a, b.q) && lpIntersect(a, b.p))
    return true;
  if (spIntersect(b, a.p) && lpIntersect(b, a.q))
    return true;
  if (spIntersect(b, a.q) && lpIntersect(b, a.p))
    return true;
  return false;
}

// ¤ÊÚüðresÉÇÁ·é
void getCommonTangent(vector<L> &res, C c1, C c2) {
  if (c1.second > c2.second)
    swap(c1, c2);
  P dir = c1.first - c2.first;
  double dist = abs(c1.first - c2.first);
  dir = dir / dist * c2.second;
  if (dist + c1.second < c2.second - EPS)
    return; // ¬~ªå~Éàï³êÄ¢é

  for (int sgn = -1; sgn <= 1; sgn += 2) {
    double cs = (c2.second + sgn * c1.second) / dist;
    P d = P(cs, sqrt(1 - cs * cs));
    res.push_back(L(c2.first + dir * d, c2.first + dir * d * P(1, 1)));
    if (imag(d) > EPS)
      res.push_back(
          L(c2.first + dir * conj(d), c2.first + dir * conj(d) * P(1, 1)));
    if (dist + EPS < c1.second + c2.second)
      break;
  }
}

// ½p`gÌÊÏðßé
double polygonArea(G g) {
  double res = 0.0;
  for (int i = 0; i < g.size(); i++)
    res += cross(g[i], g[(i + 1) % g.size()]);
  return abs(0.5 * res);
}

// _pª½p`gÌàÉ é©Ç¤©ð»è·é
bool contains(G g, P p) {
  bool in = false;
  for (int i = 0; i < g.size(); i++) {
    P a(g[i] - p), b(g[(i + 1) % g.size()] - p);
    if (imag(a) > imag(b))
      swap(a, b);
    if (imag(a) <= 0 && 0 < imag(b))
      if (cross(a, b) < 0)
        in = !in;
    if (abs(cross(a, b)) < EPS && dot(a, b) < EPS)
      return true; // üãÉpª¶Ý
  }
  return in;
}

// ¼üÌWresÅd¡·é¼üðíµCresðXV·é
void deleteSameLine(vector<L> &res) {
  int n = res.size();
  if (n > 100)
    cout << "baka" << endl;
  for (int i = 0; i < n; i++) {
    vector<L>::iterator it = res.begin() + i + 1;
    while (it < res.end()) {
      if (sameLine(
              res[i],
              (*it))) { /* ±±ðÏ¦êÎpªø­ */
        it = res.erase(it);
        n--;
        if (!n)
          return;
      } else {
        it++;
      }
    }
  }
}

int main() {
  int n;
  while (cin >> n) {
    if (!n)
      break;
    vi x, y, r, m;
    FOR(i, n) {
      int tx, ty, tr, tm;
      cin >> tx >> ty >> tr >> tm;
      x.push_back(tx);
      y.push_back(ty);
      r.push_back(tr);
      m.push_back(tm);
    }
    if (n == 1) {
      cout << 1 << endl;
      continue;
    }
    vector<L> all;
    FORic(i, 0, n - 2) {
      FORic(j, i + 1, n - 1) {
        getCommonTangent(all, C(P(x[i], y[i]), r[i]), C(P(x[j], y[j]), r[j]));
        getCommonTangent(all, C(P(x[i], y[i]), r[i] + m[i]),
                         C(P(x[j], y[j]), r[j]));
        getCommonTangent(all, C(P(x[i], y[i]), r[i]),
                         C(P(x[j], y[j]), r[j] + m[j]));
        getCommonTangent(all, C(P(x[i], y[i]), r[i] + m[i]),
                         C(P(x[j], y[j]), r[j] + m[j]));
      }
    }
    deleteSameLine(all);
    int ans = 0;
    FOR(i, SIZE(all)) {
      int count = 0;
      FOR(j, n) {
        double d = distLP(all[i], P(x[j], y[j]));
        if (r[j] < d + EPS && d - EPS < r[j] + m[j])
          count++;
      }
      ans = max(ans, count);
    }
    cout << ans << endl;
  }
  return 0;
}