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

#include "bits/stdc++.h"
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
#define INF 1 << 30
#define LINF 1LL << 60

typedef long double ld;
typedef complex<ld> Point;
const ld eps = 1e-9, pi = acos(-1.0);
namespace std {
bool operator<(const Point &lhs, const Point &rhs) {
  if (lhs.real() < rhs.real() - eps)
    return true;
  if (lhs.real() > rhs.real() + eps)
    return false;
  return lhs.imag() < rhs.imag();
}
} // namespace std
Point input_point() {
  ld x, y;
  cin >> x >> y;
  return Point(x, y);
} // 点の入力
bool eq(ld a, ld b) { return (abs(a - b) < eps); } // 誤差つき等号判定
ld dot(Point a, Point b) { return real(conj(a) * b); }   // 内積
ld cross(Point a, Point b) { return imag(conj(a) * b); } // 外積

ll W, H, A, B, S;
ld ra, rb;
ld check(ld theta) {
  ld res = 0.0;

  ld x = ra * cos(theta / 2), y = ra * sin(theta / 2);

  ld x2 = sqrt(rb * rb - y * y);
  ld ox = x2 + x;

  ld theta2 = 2 * asin(y / rb);

  ld SAB = 0.5 * ra * ra * sin(theta) + 0.5 * rb * rb * sin(theta2);

  ld S1 = pi * ra * ra * theta / (2 * pi);
  ld S2 = pi * rb * rb * theta2 / (2 * pi);

  res = S1 + S2 - SAB;
  return res;
}

int main(void) {
  cin.tie(0);
  ios::sync_with_stdio(false);
  while (cin >> W >> H >> A >> B >> S, W | H | A | B | S) {
    bool f = false;
    if (A > B) {
      swap(A, B);
      f = true;
    }
    ra = sqrt(A / pi);
    rb = sqrt(B / pi);
    ld l = 0, r = 2 * pi;
    for (int i = 0; i < 300; i++) {
      ld m = (l + r) / 2.0;
      ld area = check(m);
      if (area > S) {
        r = m;
      } else {
        l = m;
      }
    }
    ld theta = r;

    ld XA, YA, XB, YB;

    XB = rb + 0.0001;
    YB = rb + 0.0001;

    if (XB + rb > (ld)W + 0.0001 || (YB + rb) > (ld)H + 0.0001) {
      cout << "impossible" << endl;
      continue;
    }

    ld x = ra * cos(theta / 2), y = ra * sin(theta / 2);
    ld x2 = sqrt(rb * rb - y * y);
    ld ox = x2 + x;

    bool f2 = false;
    for (ld T = 0.0; T < pi + eps; T += 0.0001) {
      ld X = XB + ox * cos(T);
      ld Y = YB + ox * sin(T);
      if (((X + ra) < (ld)W + 0.0001) && ((X - ra) > -0.0001)) {
        if (((Y + ra) < (ld)H + 0.0001) && ((Y - ra) > -0.0001)) {
          XA = X;
          YA = Y;
          f2 = true;
          break;
        }
      }
    }
    if (!f2) {
      cout << "impossible" << endl;
      continue;
    }
    if (f) {
      swap(XA, XB);
      swap(YA, YB);
      swap(ra, rb);
    }
    cout << fixed << setprecision(10) << XA << " " << YA << " " << ra << " "
         << XB << " " << YB << " " << rb << endl;
  }
  return 0;
}

Error: TLE

Fixed submission:

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

using VI = vector<int>;
using VVI = vector<VI>;
using PII = pair<int, int>;
using LL = long long;
using VL = vector<LL>;
using VVL = vector<VL>;
using PLL = pair<LL, LL>;
using VS = vector<string>;

#define ALL(a) begin((a)), end((a))
#define RALL(a) (a).rbegin(), (a).rend()
#define PB push_back
#define EB emplace_back
#define MP make_pair
#define SZ(a) int((a).size())
#define SORT(c) sort(ALL((c)))
#define RSORT(c) sort(RALL((c)))
#define UNIQ(c) (c).erase(unique(ALL((c))), end((c)))

#define FOR(i, a, b) for (int i = (a); i < (b); ++i)
#define REP(i, n) FOR(i, 0, n)

#define FF first
#define SS second
template <class S, class T> istream &operator>>(istream &is, pair<S, T> &p) {
  return is >> p.FF >> p.SS;
}
template <class S, class T>
ostream &operator<<(ostream &os, const pair<S, T> &p) {
  return os << p.FF << " " << p.SS;
}
template <class T> void maxi(T &x, T y) {
  if (x < y)
    x = y;
}
template <class T> void mini(T &x, T y) {
  if (x > y)
    x = y;
}

const double EPS = 1e-6;
const double PI = acos(-1.0);
const LL MOD = 1e9 + 7;

class Point {
public:
  double x, y;

  Point(double x = 0.0, double y = 0.0) : x(x), y(y) {}

  Point &operator+=(const Point &p) {
    x += p.x;
    y += p.y;
    return *this;
  }
  Point operator+(const Point &p) const {
    Point q = *this;
    return q += p;
  }
  Point &operator-=(const Point &p) {
    x -= p.x;
    y -= p.y;
    return *this;
  }
  Point operator-(const Point &p) const {
    Point q = *this;
    return q -= p;
  }
  Point &operator*=(double a) {
    x *= a;
    y *= a;
    return *this;
  }
  Point operator*(double a) const {
    Point q = *this;
    return q *= a;
  }
  Point &operator/=(double a) {
    x /= a;
    y /= a;
    return *this;
  }
  Point operator/(double a) const {
    Point q = *this;
    return q /= a;
  }

  double abs() const { return sqrt(norm()); }
  double norm() const { return x * x + y * y; }
  Point &normalize() { return *this /= abs(); }

  bool operator<(const Point &p) const { return x != p.x ? x < p.x : y < p.y; }

  // EPSは十分小さな値
  bool operator==(const Point &p) const {
    return fabs(x - p.x) < EPS && fabs(y - p.y) < EPS;
  }
  friend ostream &operator<<(ostream &os, const Point &p);
};
ostream &operator<<(ostream &os, const Point &p) {
  return os << "(" << p.x << "," << p.y << ")";
}
class Segment {
public:
  Point p1, p2;
  Segment() {}
  Segment(const Point &p1_, const Point &p2_) : p1(p1_), p2(p2_) {}
};
class Circle {
public:
  Point c;
  double r;
  double area() const { return r * r * PI; }
};
typedef Point Vector;
typedef Segment Line;
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(Line s, Point p) {
  Vector base = s.p2 - s.p1;
  double r = dot(p - s.p1, base) / base.norm();
  return s.p1 + base * r;
}
Point rotate(Point p, double angle) {
  return Point(p.x * cos(angle) - p.y * sin(angle),
               p.x * sin(angle) + p.y * cos(angle));
}

pair<Point, Point> getCrossPoints(const Circle &c1, const Circle &c2) {
  double d = (c2.c - c1.c).abs();
  double a = (c1.r * c1.r + d * d - c2.r * c2.r) / (2 * d);
  Vector e = (c2.c - c1.c) / d;
  Vector h = rotate(e, PI / 2) * sqrt(max(c1.r * c1.r - a * a, 0.));
  if (d + min(c1.r, c2.r) <= max(c1.r, c2.r))
    return MP(c1.c + e * c1.r, c1.c + e * c1.r);

  return MP(c1.c + e * a + h, c1.c + e * a - h);
}
double getDistanceLP(Line l, Point p) {
  return abs(cross(l.p2 - l.p1, p - l.p1) / (l.p2 - l.p1).abs());
}

double getArea(Circle c1, Circle c2) {
  if (c2.r > c1.r)
    swap(c2, c1);

  Vector dr = c1.c - c2.c;
  Line ldr;
  ldr.p1 = c1.c;
  ldr.p2 = c2.c;
  double sr = (c1.r + c2.r);
  if (dr.norm() > sr * sr)
    return 0.;
  if (dr.abs() + c2.r <= c1.r)
    return c2.area();

  auto cp = getCrossPoints(c1, c2);
  Line lcp;
  lcp.p1 = cp.FF;
  lcp.p2 = cp.SS;
  double h = getDistanceLP(ldr, cp.FF);

  double d = getDistanceLP(lcp, c1.c);
  double theta = abs(atan2(h, d));
  double sg = dot(dr, cp.FF - c1.c);
  double res = c1.r * c1.r * theta + (sg >= 0 ? -1 : -1) * d * h;

  d = getDistanceLP(lcp, c2.c);
  theta = abs(atan2(h, d));
  sg = dot(dr, cp.FF - c2.c);
  res += c2.r * c2.r * theta + (sg >= 0 ? -1 : -1) * d * h;

  return res;
}

int W, H, A, B, AB;
const double DELTA = 0.0001;
bool ok(const Circle &c1, Circle &c2) {
  const double UW = W - c2.r;
  double lbx = c2.r, ubx = W - c2.r;

  for (double x = c2.r; x <= UW; x += DELTA) {
    double lby = c2.r, uby = c1.c.y;
    c2.c.x = x;
    c2.c.y = lby;
    double lba = getArea(c1, c2) - AB;
    c2.c.y = uby;
    double uba = getArea(c1, c2) - AB;
    if (lba * uba > EPS)
      continue;

    REP(it, 100) {
      double y = (lby + uby) / 2.;
      c2.c.y = y;
      double a = getArea(c1, c2) - AB;

      if (abs(a) < 1e-4) {
        return true;
      }
      if (a > 0.)
        uby = y;
      else
        lby = y;
    }
  }

  return false;
}

int main() {
  cin.tie(0);
  ios_base::sync_with_stdio(false);
  const double SQP = sqrt(PI);
  const string IMP = "impossible";
  while (cin >> W >> H >> A >> B >> AB, W) {
    Circle ca, cb;
    ca.r = sqrt(A) / SQP;
    cb.r = sqrt(B) / SQP;
    double R = min(W, H) / 2.;
    if (ca.r > R || cb.r > R) {
      cout << IMP << endl;
      continue;
    }

    bool irekawatteru = false;
    if (A < B) {
      swap(ca, cb);
      irekawatteru = true;
    }

    ca.c = Point(ca.r, ca.r);
    if (ok(ca, cb)) {
      if (irekawatteru)
        swap(ca, cb);
      cout << fixed << setprecision(9) << ca.c.x << " " << ca.c.y << " " << ca.r
           << " " << cb.c.x << " " << cb.c.y << " " << cb.r << endl;
    } else {
      ca.c = Point(ca.r, H / 2.);
      if (ok(ca, cb)) {
        if (irekawatteru)
          swap(ca, cb);
        cout << fixed << setprecision(9) << ca.c.x << " " << ca.c.y << " "
             << ca.r << " " << cb.c.x << " " << cb.c.y << " " << cb.r << endl;
      } else {
        cout << IMP << endl;
      }
    }
    // cout<<ca.area()<<","<<cb.area()<<","<<getArea(ca,cb)<<endl;
  }

  return 0;
}