三点确定圆的方法是求两对点的连线垂直平分线再求交点
过不了样例 /kk
#include <bits/stdc++.h>
#define clear(lis) memset(lis, 0, sizeof(lis))
#define full(lis) memset(lis, 0x3f, sizeof(lis))
#define fornext(x,i) for(int i = head[x]; i; i = nxt[i])
#define mset(lis,b) memset(lis, b, sizeof(lis))
#define dbg cout<<"c "
#define Rep(i,lis,b) for(int i = (lis); i <= (b); ++i)
#define IOset(lis) freopen(lis".in", "r", stdin), freopen(lis".out", "w", stdout);
using namespace std;
typedef long long ll;
typedef double db;
const int N = 1e5 + 5;
int n, lis[N];
double x[N], y[N];
double nowx, nowy, r;//当前圆心,半径
inline double dis(int a) { //lis[a]到圆心的距离
return sqrt((x[lis[a]] - nowx) * (x[lis[a]] - nowx) + (y[lis[a]] - nowy) * (y[lis[a]] - nowy));
}
struct line {
double k, b;
};
line calc(db xa, db ya, db xb, db yb) { //返回经过两点连线中点,垂直于两点连线的直线解析式
db tmp = - (xb - xa) / (yb - ya);
return (line) {tmp, (ya + yb) / 2 - (xa + xb) / 2 * tmp};
}
void reSituate(int a, int b, int c) { //三点重新确定圆
line la = calc(x[lis[a]], y[lis[a]], x[lis[b]], y[lis[b]]);
line lb = calc(x[lis[b]], y[lis[b]], x[lis[c]], y[lis[c]]);
nowx = (lb.b - la.b) / (la.k - lb.k);
nowy = la.k * nowx + la.b;
r = dis(a);
}
int main() {
srand(233);
cin >> n;
Rep(i, 1, n) scanf("%lf%lf", &x[i], &y[i]);
Rep(i, 1, n) lis[i] = i;
random_shuffle(lis + 1, lis + n + 1); //随机化
nowx = x[lis[1]], nowy = y[lis[1]], r = 0;
Rep(i, 2, n) {
cout<<r<<endl;
if (dis(i) <= r) continue;
nowx = x[lis[i]], nowy = y[lis[i]], r = 0;
for (int j = 1; j <= i - 1; ++j) {
if (dis(j) <= r) continue;
nowx = (x[lis[i]] + x[lis[j]]) / 2, nowy = (y[lis[i]] + y[lis[j]]) / 2;
r = dis(i);
for (int k = 1; k <= j - 1; ++k) {
if (dis(k) <= r) continue;
reSituate(i, j, k);
}
}
}
printf("%.2f\n%.2f %.2f\n", r, nowx, nowy);
return 0;
}