版权声明:欢迎大家转载,转载请注明出处 https://blog.csdn.net/hao_zong_yin/article/details/82633554
随机选三个点, 选错的概率是0.5*0.5*0.5,重复次数越多出错率越低。所以无限循环直到找到解就可以了,注意特判n<=4的情况,此时一个圆只要包含两个点就可以,不用三点确定圆
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 10;
const double eps = 1e-8;
int dcmp(double x) { if (fabs(x) < eps) return 0; else return x < 0 ? -1 : 1; }
struct Point {
double x, y;
Point(double x = 0, double y = 0) : x(x), y(y) {}
}point[maxn];
struct Line { Point a, b; };
typedef Point Vector;
Vector operator + (Vector A, Vector B) { return Vector(A.x+B.x, A.y+B.y); }
Vector operator - (Vector A, Vector B) { return Vector(A.x-B.x, A.y-B.y); }
Vector operator * (Vector A, double p) { return Vector(A.x*p, A.y*p); }
Vector operator / (Vector A, double p) { return Vector(A.x/p, A.y/p); }
Point cal(Point a, Point b, Point c) {
Point cp;
double a1 = b.x - a.x, b1 = b.y - a.y, c1 = (a1*a1 + b1*b1) / 2;
double a2 = c.x - a.x, b2 = c.y - a.y, c2 = (a2*a2 + b2*b2) / 2;
double d = a1 * b2 - a2*b1;
cp.x = a.x + (c1*b2 - c2*b1) / d;
cp.y = a.y + (a1*c2 - a2*c1) / d;
return cp;
}
double dis(Point a, Point b) { return sqrt((a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y)); }
int main() {
srand((unsigned int)time(0));
int T, n;
scanf("%d", &T);
while (T--) {
Point ans;
double ansR;
scanf("%d", &n);
for (int i = 1; i <= n; i++) scanf("%lf%lf", &point[i].x, &point[i].y);
if(n == 1){
printf("%.6f %.6f 1\n",point[1].x+1, point[1].y);
continue;
}
if(n <= 4){
double x = (point[1].x + point[2].x)/2;
double y = (point[1].y + point[2].y)/2;
double r = dis(point[1], point[2])/2;
printf("%.6f %.6f %.6f\n",x,y,r);
continue;
}
while (1) {
int idx1 = rand() % n + 1, idx2 = rand() % n + 1, idx3 = rand() % n + 1;
if (idx1 == idx2 || idx1 == idx3 || idx2 == idx3) continue;
Point a = point[idx1], b = point[idx2], c = point[idx3];
if (dcmp((a.y-b.y)*(b.x-c.x)-(a.x-b.x)*(b.y-c.y)) == 0) continue;
Point center = cal(a, b, c);
double R = dis(center, a);
int cnt = 0;
for (int i = 1; i <= n; i++) {
if (dcmp(dis(point[i], center) - R) == 0) cnt++;
}
if (cnt >= (int)ceil(1.0*n/2)) {
if (fabs(center.x) > 1e9 || fabs(center.y) > 1e9 || fabs(R) > 1e9) continue;
ans = center, ansR = R;
break;
}
}
printf("%.6f %.6f %.6f\n", ans.x, ans.y, ansR);
}
return 0;
}