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

#include <bits/stdc++.h>
#define f first
#define s second
#define mp make_pair
#define pi M_PI
#define inf 600000
#define eps (1e-11)
#define equals(a, b) (fabs((a) - (b)) < eps)
using namespace std;

class Point {
public:
  double x, y;
  Point(double x = 0, double y = 0) : x(x), y(y) {}

  Point operator+(Point p) { return Point(x + p.x, y + p.y); }
  Point operator-(Point p) { return Point(x - p.x, y - p.y); }
  Point operator*(double k) { return Point(x * k, y * k); }
  Point operator/(double k) { return Point(x / k, y / k); }
  bool operator<(Point p) const { return (x != p.x ? x < p.x : y < p.y); }
  bool operator==(Point p) const {
    return fabs(x - p.x) < eps && fabs(y - p.y) < eps;
  }

  double abs() { return sqrt(norm()); }
  double norm() { return (x * x + y * y); }
};
typedef Point Vector;

class Segment {
public:
  Point p1, p2;
  Segment(Point p1 = Point(), Point p2 = Point()) : p1(p1), p2(p2) {}
};
typedef Segment Line;

class Circle {
public:
  Point c;
  double r;
  Circle(Point c = Point(), double r = 0.0) : c(c), r(r) {}
};

double norm(Vector a) { return (a.x * a.x + a.y * a.y); }
double abs(Vector a) { return sqrt(norm(a)); }
double dot(Vector a, Vector b) { return (a.x * b.x + a.y * b.y); }
double cross(Vector a, Vector b) { return (a.x * b.y - a.y * b.x); }

Point project(Segment s, Point p) {
  Vector base = (s.p2 - s.p1);
  double r = (dot(p - s.p1, base) / base.norm());
  return (s.p1 + base * r);
}

pair<Point, Point> getCrossPoints(Circle c, Line l) {
  Vector pr = project(l, c.c);
  Vector e = (l.p2 - l.p1) / abs(l.p2 - l.p1);
  double base = sqrt(c.r * c.r - norm(pr - c.c));
  return mp(pr + e * base, pr - e * base);
}

double getDistanceLP(Line l, Point p) {
  return abs(cross(l.p2 - l.p1, p - l.p1) / abs(l.p2 - l.p1));
}

bool intersect(Circle c, Line L) {
  double dis = getDistanceLP(L, c.c);
  if ((dis - c.r) < eps)
    return true;
  return false;
}

int n;
vector<Circle> vc;

bool ok(double mid) {

  Line L(Point(-inf, mid), Point(inf, mid));
  vector<pair<double, double>> v;
  for (int i = 0; i < n; i++) {
    if (!intersect(vc[i], L))
      continue;
    pair<Point, Point> pp = getCrossPoints(vc[i], L);
    double mind = min(pp.f.x, pp.s.x), maxd = max(pp.f.x, pp.s.x);
    v.push_back(mp(mind, maxd));
  }
  v.push_back(mp(inf, inf));

  double sum = 0, x = v[0].f;
  for (int i = 0; i < v.size() - 1; i++) {
    if (v[i].f < v[i + 1].f && v[i + 1].s < v[i].s) {
      sum += abs(x - v[i].s);
      if ((mid * 2 - sum) < eps)
        return true;
      x = v[i + 2].f;
      sum = 0;
      i++;
      continue;
    }
    if (v[i + 1].f < v[i].f && v[i].s < v[i + 1].s) {
      x = v[i + 1].f;
      continue;
    }
    sum += abs(v[i].s - x);
    if (v[i + 1].f < v[i].s)
      x = v[i].s;
    else {
      if ((mid * 2 - sum) < eps)
        return true;
      sum = 0;
      x = v[i + 1].f;
    }
  }
  return false;
}

int main() {
  double x, r;

  while (1) {
    cin >> n;
    if (n == 0)
      break;
    vc.clear();
    double maxr = 0;
    for (int i = 0; i < n; i++) {
      cin >> x >> r;
      vc.push_back(Circle(Point(x, 0), r));
      maxr = max(maxr, r);
    }

    double l = 0;
    r = maxr;
    for (int i = 0; i < 40; i++) {
      double m = (l + r) / 2.0;
      if (ok(m))
        l = m;
      else
        r = m;
    }
    printf("%.10f\\n", l * 2);
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>
#define f first
#define s second
#define mp make_pair
#define pi M_PI
#define inf 600000
#define eps (1e-11)
#define equals(a, b) (fabs((a) - (b)) < eps)
using namespace std;

class Point {
public:
  double x, y;
  Point(double x = 0, double y = 0) : x(x), y(y) {}

  Point operator+(Point p) { return Point(x + p.x, y + p.y); }
  Point operator-(Point p) { return Point(x - p.x, y - p.y); }
  Point operator*(double k) { return Point(x * k, y * k); }
  Point operator/(double k) { return Point(x / k, y / k); }
  bool operator<(Point p) const { return (x != p.x ? x < p.x : y < p.y); }
  bool operator==(Point p) const {
    return fabs(x - p.x) < eps && fabs(y - p.y) < eps;
  }

  double abs() { return sqrt(norm()); }
  double norm() { return (x * x + y * y); }
};
typedef Point Vector;

class Segment {
public:
  Point p1, p2;
  Segment(Point p1 = Point(), Point p2 = Point()) : p1(p1), p2(p2) {}
};
typedef Segment Line;

class Circle {
public:
  Point c;
  double r;
  Circle(Point c = Point(), double r = 0.0) : c(c), r(r) {}
};

double norm(Vector a) { return (a.x * a.x + a.y * a.y); }
double abs(Vector a) { return sqrt(norm(a)); }
double dot(Vector a, Vector b) { return (a.x * b.x + a.y * b.y); }
double cross(Vector a, Vector b) { return (a.x * b.y - a.y * b.x); }

Point project(Segment s, Point p) {
  Vector base = (s.p2 - s.p1);
  double r = (dot(p - s.p1, base) / base.norm());
  return (s.p1 + base * r);
}

pair<Point, Point> getCrossPoints(Circle c, Line l) {
  Vector pr = project(l, c.c);
  Vector e = (l.p2 - l.p1) / abs(l.p2 - l.p1);
  double base = sqrt(c.r * c.r - norm(pr - c.c));
  return mp(pr + e * base, pr - e * base);
}

double getDistanceLP(Line l, Point p) {
  return abs(cross(l.p2 - l.p1, p - l.p1) / abs(l.p2 - l.p1));
}

bool intersect(Circle c, Line L) {
  double dis = getDistanceLP(L, c.c);
  if ((dis - c.r) < eps)
    return true;
  return false;
}

int n;
vector<Circle> vc;

bool ok(double mid) {

  Line L(Point(-inf, mid), Point(inf, mid));
  vector<pair<double, double>> v;
  for (int i = 0; i < n; i++) {
    if (!intersect(vc[i], L))
      continue;
    pair<Point, Point> pp = getCrossPoints(vc[i], L);
    double mind = min(pp.f.x, pp.s.x), maxd = max(pp.f.x, pp.s.x);
    v.push_back(mp(mind, maxd));
  }
  v.push_back(mp(inf, inf));

  int size = v.size();
  for (int i = 0; i < size - 1; i++) {
    if (v[i].f < v[i + 1].f && v[i + 1].s < v[i].s) {
      v.erase(v.begin() + i + 1);
      i--;
      size = v.size();
    } else if (v[i + 1].f < v[i].f && v[i].s < v[i + 1].s) {
      v.erase(v.begin() + i);
      i--;
      size = v.size();
    }
  }
  double sum = 0, x = v[0].f;
  for (int i = 0; i < v.size() - 1; i++) {
    sum += abs(v[i].s - x);
    if (v[i + 1].f < v[i].s)
      x = v[i].s;
    else {
      if ((mid * 2 - sum) < eps)
        return true;
      sum = 0;
      x = v[i + 1].f;
    }
  }
  // cout<<v[0].f<<" "<<v[0].s<<endl;
  if ((mid * 2 - sum) < eps)
    return true;
  return false;
}

int main() {
  double x, r;

  while (1) {
    cin >> n;
    if (n == 0)
      break;
    vc.clear();
    double maxr = 0;
    for (int i = 0; i < n; i++) {
      cin >> x >> r;
      vc.push_back(Circle(Point(x, 0), r));
      maxr = max(maxr, r);
    }

    double l = 0;
    r = maxr;
    for (int i = 0; i < 50; i++) {
      double m = (l + r) / 2.0;
      if (ok(m))
        l = m;
      else
        r = m;
    }
    printf("%.10f\\n", l * 2);
  }
  return 0;
}