Problem p02805 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
using namespace std;

// #define int long long
#define rep(i, n) for (long long i = (long long)(0); i < (long long)(n); ++i)
#define reps(i, n) for (long long i = (long long)(1); i <= (long long)(n); ++i)
#define rrep(i, n) for (long long i = ((long long)(n)-1); i >= 0; i--)
#define rreps(i, n) for (long long i = ((long long)(n)); i > 0; i--)
#define irep(i, m, n)                                                          \
  for (long long i = (long long)(m); i < (long long)(n); ++i)
#define ireps(i, m, n)                                                         \
  for (long long i = (long long)(m); i <= (long long)(n); ++i)
#define SORT(v, n) sort(v, v + n);
#define REVERSE(v, n) reverse(v, v + n);
#define vsort(v) sort(v.begin(), v.end());
#define all(v) v.begin(), v.end()
#define mp(n, m) make_pair(n, m);
#define cout(d) cout << d << endl;
#define coutd(d) cout << std::setprecision(10) << d << endl;
#define cinline(n) getline(cin, n);
#define replace_all(s, b, a) replace(s.begin(), s.end(), b, a);
// #define PI (acos(-1))
#define FILL(v, n, x) fill(v, v + n, x);
#define sz(x) long long(x.size())

using ll = long long;
using vi = vector<int>;
using vvi = vector<vi>;
using vll = vector<ll>;
using vvll = vector<vll>;
using pii = pair<int, int>;
using pll = pair<ll, ll>;
using vs = vector<string>;
using vpll = vector<pair<ll, ll>>;
using vtp = vector<tuple<ll, ll, ll>>;
using vb = vector<bool>;

template <class T> inline bool chmax(T &a, T b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T> inline bool chmin(T &a, T b) {
  if (a > b) {
    a = b;
    return 1;
  }
  return 0;
}

// const ll INF = 1e9;
const ll MOD = 1e9 + 7;
const ll LINF = 1e18;

// 参考: https://drken1215.hatenablog.com/entry/2020/01/12/224200

/* 幾何ライブラリ */
using DD = double;
const DD INF = 1LL << 60; // to be set appropriately
const DD EPS = 1e-10;     // to be set appropriately
const DD PI = acosl(-1.0);
DD torad(int deg) { return (DD)(deg)*PI / 180; }
DD todeg(DD ang) { return ang * 180 / PI; }

/* Point */
struct Point {
  DD x, y;
  Point(DD x = 0.0, DD y = 0.0) : x(x), y(y) {}
  friend ostream &operator<<(ostream &s, const Point &p) {
    return s << '(' << p.x << ", " << p.y << ')';
  }
};
inline Point operator+(const Point &p, const Point &q) {
  return Point(p.x + q.x, p.y + q.y);
}
inline Point operator-(const Point &p, const Point &q) {
  return Point(p.x - q.x, p.y - q.y);
}
inline Point operator*(const Point &p, DD a) { return Point(p.x * a, p.y * a); }
inline Point operator*(DD a, const Point &p) { return Point(a * p.x, a * p.y); }
inline Point operator*(const Point &p, const Point &q) {
  return Point(p.x * q.x - p.y * q.y, p.x * q.y + p.y * q.x);
}
inline Point operator/(const Point &p, DD a) { return Point(p.x / a, p.y / a); }
inline Point conj(const Point &p) { return Point(p.x, -p.y); }
inline Point rot(const Point &p, DD ang) {
  return Point(cos(ang) * p.x - sin(ang) * p.y,
               sin(ang) * p.x + cos(ang) * p.y);
}
inline Point rot90(const Point &p) { return Point(-p.y, p.x); }
inline DD cross(const Point &p, const Point &q) {
  return p.x * q.y - p.y * q.x;
}
inline DD dot(const Point &p, const Point &q) { return p.x * q.x + p.y * q.y; }
inline DD norm(const Point &p) { return dot(p, p); }
inline DD abs(const Point &p) { return sqrt(dot(p, p)); }
inline DD amp(const Point &p) {
  DD res = atan2(p.y, p.x);
  if (res < 0)
    res += PI * 2;
  return res;
}
inline bool eq(const Point &p, const Point &q) { return abs(p - q) < EPS; }
inline bool operator<(const Point &p, const Point &q) {
  return (abs(p.x - q.x) > EPS ? p.x < q.x : p.y < q.y);
}
inline bool operator>(const Point &p, const Point &q) {
  return (abs(p.x - q.x) > EPS ? p.x > q.x : p.y > q.y);
}
inline Point operator/(const Point &p, const Point &q) {
  return p * conj(q) / norm(q);
}

/* Line */
struct Line : vector<Point> {
  Line(Point a = Point(0.0, 0.0), Point b = Point(0.0, 0.0)) {
    this->push_back(a);
    this->push_back(b);
  }
  friend ostream &operator<<(ostream &s, const Line &l) {
    return s << '{' << l[0] << ", " << l[1] << '}';
  }
};

// 1：a-bから見てcは左側(反時計回り)、-1：a-bから見てcは右側(時計回り)、0：一直線上
int simple_ccw(const Point &a, const Point &b, const Point &c) {
  if (cross(b - a, c - a) > EPS)
    return 1;
  if (cross(b - a, c - a) < -EPS)
    return -1;
  return 0;
}

// 円や直線の交点
vector<Point> crosspoint(const Line &l, const Line &m) {
  vector<Point> res;
  DD d = cross(m[1] - m[0], l[1] - l[0]);
  if (abs(d) < EPS)
    return vector<Point>();
  res.push_back(l[0] + (l[1] - l[0]) * cross(m[1] - m[0], m[1] - l[0]) / d);
  return res;
}

// 外心
Point gaisin(Point a, Point b, Point c) {
  Line ab((a + b) / 2, (a + b) / 2 + rot90(a - b));
  Line bc((b + c) / 2, (b + c) / 2 + rot90(b - c));
  return crosspoint(ab, bc)[0];
}

signed main() {
  cin.tie(0);
  ios::sync_with_stdio(false);

  ll n;
  cin >> n;
  vector<Point> v(n);
  rep(i, n) { cin >> v[i].x >> v[i].y; }

  vector<Point> cond; // 候補
  rep(i, n) irep(j, i + 1, n) {
    cond.push_back((v[i] + v[j]) / 2);
    irep(k, j + 1, n) {
      if (simple_ccw(v[i], v[j], v[k]))
        continue;
      auto p = gaisin(v[i], v[j], v[k]);
      cond.push_back(p);
    }
  }

  double ans = INF;
  for (auto e : cond) {
    double tmp = 0;
    rep(i, n) chmax(tmp, abs(e - v[i]));
    chmin(ans, tmp);
  }

  cout << std::setprecision(10) << ans << endl;
}

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

// #define int long long
#define rep(i, n) for (long long i = (long long)(0); i < (long long)(n); ++i)
#define reps(i, n) for (long long i = (long long)(1); i <= (long long)(n); ++i)
#define rrep(i, n) for (long long i = ((long long)(n)-1); i >= 0; i--)
#define rreps(i, n) for (long long i = ((long long)(n)); i > 0; i--)
#define irep(i, m, n)                                                          \
  for (long long i = (long long)(m); i < (long long)(n); ++i)
#define ireps(i, m, n)                                                         \
  for (long long i = (long long)(m); i <= (long long)(n); ++i)
#define SORT(v, n) sort(v, v + n);
#define REVERSE(v, n) reverse(v, v + n);
#define vsort(v) sort(v.begin(), v.end());
#define all(v) v.begin(), v.end()
#define mp(n, m) make_pair(n, m);
#define cout(d) cout << d << endl;
#define coutd(d) cout << std::setprecision(10) << d << endl;
#define cinline(n) getline(cin, n);
#define replace_all(s, b, a) replace(s.begin(), s.end(), b, a);
// #define PI (acos(-1))
#define FILL(v, n, x) fill(v, v + n, x);
#define sz(x) long long(x.size())

using ll = long long;
using vi = vector<int>;
using vvi = vector<vi>;
using vll = vector<ll>;
using vvll = vector<vll>;
using pii = pair<int, int>;
using pll = pair<ll, ll>;
using vs = vector<string>;
using vpll = vector<pair<ll, ll>>;
using vtp = vector<tuple<ll, ll, ll>>;
using vb = vector<bool>;

template <class T> inline bool chmax(T &a, T b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T> inline bool chmin(T &a, T b) {
  if (a > b) {
    a = b;
    return 1;
  }
  return 0;
}

// const ll INF = 1e9;
const ll MOD = 1e9 + 7;
const ll LINF = 1e18;

// 参考: https://drken1215.hatenablog.com/entry/2020/01/12/224200

/* 幾何ライブラリ */
using DD = double;
const DD INF = 1LL << 60; // to be set appropriately
const DD EPS = 1e-10;     // to be set appropriately
const DD PI = acosl(-1.0);
DD torad(int deg) { return (DD)(deg)*PI / 180; }
DD todeg(DD ang) { return ang * 180 / PI; }

/* Point */
struct Point {
  DD x, y;
  Point(DD x = 0.0, DD y = 0.0) : x(x), y(y) {}
  friend ostream &operator<<(ostream &s, const Point &p) {
    return s << '(' << p.x << ", " << p.y << ')';
  }
};
inline Point operator+(const Point &p, const Point &q) {
  return Point(p.x + q.x, p.y + q.y);
}
inline Point operator-(const Point &p, const Point &q) {
  return Point(p.x - q.x, p.y - q.y);
}
inline Point operator*(const Point &p, DD a) { return Point(p.x * a, p.y * a); }
inline Point operator*(DD a, const Point &p) { return Point(a * p.x, a * p.y); }
inline Point operator*(const Point &p, const Point &q) {
  return Point(p.x * q.x - p.y * q.y, p.x * q.y + p.y * q.x);
}
inline Point operator/(const Point &p, DD a) { return Point(p.x / a, p.y / a); }
inline Point conj(const Point &p) { return Point(p.x, -p.y); }
inline Point rot(const Point &p, DD ang) {
  return Point(cos(ang) * p.x - sin(ang) * p.y,
               sin(ang) * p.x + cos(ang) * p.y);
}
inline Point rot90(const Point &p) { return Point(-p.y, p.x); }
inline DD cross(const Point &p, const Point &q) {
  return p.x * q.y - p.y * q.x;
}
inline DD dot(const Point &p, const Point &q) { return p.x * q.x + p.y * q.y; }
inline DD norm(const Point &p) { return dot(p, p); }
inline DD abs(const Point &p) { return sqrt(dot(p, p)); }
inline DD amp(const Point &p) {
  DD res = atan2(p.y, p.x);
  if (res < 0)
    res += PI * 2;
  return res;
}
inline bool eq(const Point &p, const Point &q) { return abs(p - q) < EPS; }
inline bool operator<(const Point &p, const Point &q) {
  return (abs(p.x - q.x) > EPS ? p.x < q.x : p.y < q.y);
}
inline bool operator>(const Point &p, const Point &q) {
  return (abs(p.x - q.x) > EPS ? p.x > q.x : p.y > q.y);
}
inline Point operator/(const Point &p, const Point &q) {
  return p * conj(q) / norm(q);
}

/* Line */
struct Line : vector<Point> {
  Line(Point a = Point(0.0, 0.0), Point b = Point(0.0, 0.0)) {
    this->push_back(a);
    this->push_back(b);
  }
  friend ostream &operator<<(ostream &s, const Line &l) {
    return s << '{' << l[0] << ", " << l[1] << '}';
  }
};

// 1：a-bから見てcは左側(反時計回り)、-1：a-bから見てcは右側(時計回り)、0：一直線上
int simple_ccw(const Point &a, const Point &b, const Point &c) {
  if (cross(b - a, c - a) > EPS)
    return 1;
  if (cross(b - a, c - a) < -EPS)
    return -1;
  return 0;
}

// 円や直線の交点
vector<Point> crosspoint(const Line &l, const Line &m) {
  vector<Point> res;
  DD d = cross(m[1] - m[0], l[1] - l[0]);
  if (abs(d) < EPS)
    return vector<Point>();
  res.push_back(l[0] + (l[1] - l[0]) * cross(m[1] - m[0], m[1] - l[0]) / d);
  return res;
}

// 外心
Point gaisin(Point a, Point b, Point c) {
  Line ab((a + b) / 2, (a + b) / 2 + rot90(a - b));
  Line bc((b + c) / 2, (b + c) / 2 + rot90(b - c));
  return crosspoint(ab, bc)[0];
}

signed main() {
  cin.tie(0);
  ios::sync_with_stdio(false);

  ll n;
  cin >> n;
  vector<Point> v(n);
  rep(i, n) { cin >> v[i].x >> v[i].y; }

  vector<Point> cond; // 候補
  rep(i, n) irep(j, i + 1, n) {
    cond.push_back((v[i] + v[j]) / 2);
    irep(k, j + 1, n) {
      if (simple_ccw(v[i], v[j], v[k]) == 0)
        continue;
      auto p = gaisin(v[i], v[j], v[k]);
      cond.push_back(p);
    }
  }

  double ans = INF;
  for (auto e : cond) {
    double tmp = 0;
    rep(i, n) chmax(tmp, abs(e - v[i]));
    chmin(ans, tmp);
  }

  cout << std::setprecision(10) << ans << endl;
}