Problem p01684 (C++) — buggy submission, verdict: Runtime Error

#include <algorithm>
#include <bitset>
#include <cassert>
#include <cctype>
#include <complex>
#include <cstdio>
#include <functional>
#include <iomanip>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <utility>
#include <vector>
// #include <tuple>
// #include <regex>

using namespace std;

typedef long long ll;

#define ALL(c) (c).begin(), (c).end()
#define REP(i, n) for (int i = 0; i < (int)(n); ++i)
#define IN(l, v, r) ((l) <= (v) && (v) < (r))
stringstream ss;

typedef long double D;
const D EPS = 1e-8, INF = 1e12;

template <typename T> int sig(T a, T b = 0) {
  return a < b - EPS ? -1 : a > b + EPS ? 1 : 0;
}
template <typename T> bool eq(T a, T b) { return sig(abs(a - b)) == 0; }
template <typename T> D norm(T a) { return a * a; }

typedef complex<D> P;
#define X real()
#define Y imag()

// a×b
D cross(const P &a, const P &b) { return imag(conj(a) * b); }
// a・b
D dot(const P &a, const P &b) { return real(conj(a) * b); }

int ccw(const 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;    // same
}

// 浮動小数点modで非負の値のみかえす．
D pfmod(D v, D M = 2 * M_PI) { return fmod(fmod(v, M) + M, M); }

//[0,PI)
D AbsArg(D a) {
  D ret = pfmod(max(a, -a), 2);
  return min(ret, 2 * M_PI - ret);
}

namespace std {
bool operator<(const P &a, const P &b) {
  return a.X != b.X ? a.X < b.X : a.Y < b.Y;
}
bool operator==(const P &a, const P &b) { return eq(a, b); }
}; // namespace std

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

bool isIntersectSS(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;
}

struct C {
  P o;
  D r;
  C(const P &o, D r) : o(o), r(r) {}
};

int IINF = 1 << 28;
// 包含関係
enum RELATION { INCOMPARABLE = 0, SAME = 1, CONTAIN = 2, OVER = 4 };
pair<RELATION, int> cRel(const C &c1, const C &c2) {
  D d = abs(c1.o - c2.o), rd = c1.r - c2.r;
  if (eq(c1.o, c2.o) && eq(c1.r, c2.r))
    return make_pair(SAME, IINF); // c1 == c2
  if (sig(d, rd) < 0)
    return make_pair(OVER, 0); // c2 ⊆ c1
  if (sig(d, rd) == 0)
    return make_pair(OVER, 1); // c2 ⊆ c1,1点で接する
  if (sig(d, -rd) < 0)
    return make_pair(CONTAIN, 0); // c1 ⊆ c2
  if (sig(d, -rd) == 0)
    return make_pair(CONTAIN, 1); // c1 ⊆ c2,1点で接する
  if (sig(d, c1.r + c2.r) < 0)
    return make_pair(INCOMPARABLE, 2); //  2点で接する
  if (sig(d, c1.r + c2.r) == 0)
    return make_pair(INCOMPARABLE, 1); // 1点で接する
  return make_pair(INCOMPARABLE, 0);   // 交わらない
}
D cc_area(const C &c1, const C &c2) {
  pair<RELATION, int> rel = cRel(c1, c2);
  if (rel.first != INCOMPARABLE) { // 共通部分が円
    D r = min(c1.r, c2.r);
    return r * r * M_PI;
  }
  if (rel.second <= 1)
    return 0.0;
  D d = abs(c1.o - c2.o);
  D rlcosA = (d * d + c1.r * c1.r - c2.r * c2.r) / (2 * d);
  D A = acos(rlcosA / c1.r), B = acos((d - rlcosA) / c2.r);
  // cerr << A <<" "<<B;
  //  cout << ";"<<rlcosA<<endl;
  //  cout << ";"<<A<<" "<<B<<endl;
  //  cout << ";"<<rel.first<<" "<<rel.second<<endl;
  //  cout << c1.r*c1.r*A + c2.r*c2.r*B -d* c1.r*sin(A)<<endl;
  return c1.r * c1.r * A + c2.r * c2.r * B - d * c1.r * sin(A);
}

D getD(D Ar, D Br, D AB) {
  C cA(P(0, 0), Ar);
  D ld = 0, rd = 1e10;
  while (rd - ld > 1e-9) {
    D md = (ld + rd) / 2;

    C cB(P(md, 0), Br);
    if (cc_area(cA, cB) <= AB) {
      rd = md;
    } else {
      ld = md;
    }
  }
  return ld;
}

int main() {
  ss << fixed << setprecision(20);
  cout << fixed << setprecision(20);
  cerr << fixed << setprecision(20);

  while (true) {
    D W, H, A, B, AB;
    cin >> W >> H >> A >> B >> AB;
    if (W == 0 && H == 0 && A == 0 && B == 0 && AB == 0)
      break;

    double Ar = sqrt(A / M_PI), Br = sqrt(B / M_PI);
    bool swaped = false;
    if (Ar < Br) {
      swap(Ar, Br);
      swaped = true;
    }

    // set A
    if (2 * Ar > min(H, W)) {
      cout << "impossible" << endl;
      continue;
    }
    D d = getD(Ar, Br, AB);

    P u(W - Ar - Br, H - Ar - Br);
    if (abs(u) > EPS)
      u /= abs(u);

    C cA = C(P(Ar, Ar), Ar), cB = C(P(Ar, Ar) + u * d, Br);
    // set B
    if (cB.o.X + Br > W || cB.o.Y + Br > H) {
      cout << "impossible" << endl;
      continue;
    }

    if (swaped)
      swap(cA, cB);

    cout << cA.o.X << " " << cA.o.Y << " " << cA.r;
    cout << " " << cB.o.X << " " << cB.o.Y << " " << cB.r;
    cout << endl;

    // cerr << M_PI*cA.r*cA.r<<endl;
    // cerr << M_PI*cB.r*cB.r<<endl;
    // cerr << cc_area(cA,cB)<<endl;
  }

  return 0;
}

Error: WA

Fixed submission:

#include <algorithm>
#include <bitset>
#include <cassert>
#include <cctype>
#include <complex>
#include <cstdio>
#include <functional>
#include <iomanip>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <utility>
#include <vector>
// #include <tuple>
// #include <regex>

using namespace std;

typedef long long ll;

#define ALL(c) (c).begin(), (c).end()
#define REP(i, n) for (int i = 0; i < (int)(n); ++i)
#define IN(l, v, r) ((l) <= (v) && (v) < (r))
stringstream ss;

typedef long double D;
const D EPS = 1e-8, INF = 1e12;

template <typename T> int sig(T a, T b = 0) {
  return a < b - EPS ? -1 : a > b + EPS ? 1 : 0;
}
template <typename T> bool eq(T a, T b) { return sig(abs(a - b)) == 0; }
template <typename T> D norm(T a) { return a * a; }

typedef complex<D> P;
#define X real()
#define Y imag()

// a×b
D cross(const P &a, const P &b) { return imag(conj(a) * b); }
// a・b
D dot(const P &a, const P &b) { return real(conj(a) * b); }

int ccw(const 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;    // same
}

// 浮動小数点modで非負の値のみかえす．
D pfmod(D v, D M = 2 * M_PI) { return fmod(fmod(v, M) + M, M); }

//[0,PI)
D AbsArg(D a) {
  D ret = pfmod(max(a, -a), 2);
  return min(ret, 2 * M_PI - ret);
}

namespace std {
bool operator<(const P &a, const P &b) {
  return a.X != b.X ? a.X < b.X : a.Y < b.Y;
}
bool operator==(const P &a, const P &b) { return eq(a, b); }
}; // namespace std

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

bool isIntersectSS(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;
}

struct C {
  P o;
  D r;
  C(const P &o, D r) : o(o), r(r) {}
};

int IINF = 1 << 28;
// 包含関係
enum RELATION { INCOMPARABLE = 0, SAME = 1, CONTAIN = 2, OVER = 4 };
pair<RELATION, int> cRel(const C &c1, const C &c2) {
  D d = abs(c1.o - c2.o), rd = c1.r - c2.r;
  if (eq(c1.o, c2.o) && eq(c1.r, c2.r))
    return make_pair(SAME, IINF); // c1 == c2
  if (sig(d, rd) < 0)
    return make_pair(OVER, 0); // c2 ⊆ c1
  if (sig(d, rd) == 0)
    return make_pair(OVER, 1); // c2 ⊆ c1,1点で接する
  if (sig(d, -rd) < 0)
    return make_pair(CONTAIN, 0); // c1 ⊆ c2
  if (sig(d, -rd) == 0)
    return make_pair(CONTAIN, 1); // c1 ⊆ c2,1点で接する
  if (sig(d, c1.r + c2.r) < 0)
    return make_pair(INCOMPARABLE, 2); //  2点で接する
  if (sig(d, c1.r + c2.r) == 0)
    return make_pair(INCOMPARABLE, 1); // 1点で接する
  return make_pair(INCOMPARABLE, 0);   // 交わらない
}
D cc_area(const C &c1, const C &c2) {
  pair<RELATION, int> rel = cRel(c1, c2);
  D d = abs(c1.o - c2.o);
  if (rel.second == 0)
    return 0.0;
  if (rel.first != INCOMPARABLE) { // 共通部分が円
    D r = min(c1.r, c2.r);
    return r * r * M_PI;
  }
  D rlcosA = (d * d + c1.r * c1.r - c2.r * c2.r) / (2 * d);
  D A = acos(rlcosA / c1.r), B = acos((d - rlcosA) / c2.r);
  return c1.r * c1.r * A + c2.r * c2.r * B - d * c1.r * sin(A);
}

D getD(D Ar, D Br, D AB) {
  C cA(P(0, 0), Ar);
  D ld = 0, rd = 1e10;
  while (rd - ld > 1e-5) {
    D md = (ld + rd) / 2;

    C cB(P(md, 0), Br);
    if (cc_area(cA, cB) <= AB) {
      rd = md;
    } else {
      ld = md;
    }
  }
  return ld;
}

int main() {
  ss << fixed << setprecision(20);
  cout << fixed << setprecision(20);
  cerr << fixed << setprecision(20);

  while (true) {
    D W, H, A, B, AB;
    cin >> W >> H >> A >> B >> AB;
    if (W == 0 && H == 0 && A == 0 && B == 0 && AB == 0)
      break;

    double Ar = sqrt(A / M_PI), Br = sqrt(B / M_PI);
    bool swaped = false;
    if (Ar < Br) {
      swap(Ar, Br);
      swaped = true;
    }

    double d = getD(Ar, Br, AB);
    cerr << d << endl;
    if (W - Ar - Br < -EPS || H - Ar - Br < -EPS) {
      cout << "impossible" << endl;
      continue;
    }

    double Md = hypot(W - Ar - Br, H - Ar - Br);
    if (d > Md - EPS) {
      cout << "impossible" << endl;
      continue;
    }

    C cA = C(P(Ar, Ar), Ar),
      cB = C(P(Ar + d * cos(atan((H - (Ar + Br)) / (W - (Ar + Br)))),
               Ar + d * sin(atan((H - (Ar + Br)) / (W - (Ar + Br))))),
             Br);

    if (swaped)
      swap(cA, cB);

    cout << cA.o.X << " " << cA.o.Y << " " << cA.r;
    cout << " " << cB.o.X << " " << cB.o.Y << " " << cB.r;
    cout << endl;

    // cerr << M_PI*cA.r*cA.r<<endl;
    // cerr << M_PI*cB.r*cB.r<<endl;
    // cerr << cc_area(cA,cB)<<endl;
  }

  return 0;
}