题目链接:https://vjudge.net/problem/HDU-6242
题意:n个点,找到一个圆,满足圆上点的数目大于等于⌈N / 2⌉
题解:三个不在一条直线上的点确定一个圆,随机到圆上点的概率是1 / 2,那么三次就是1 / 8,所以如果随机找出三个点,那么找到这个圆的期望次数就是8次
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
const double eps = 1e-8;
int n;
int sgn(double x) {
if(fabs(x) < eps) return 0;
if(x < 0) return -1;
return 1;
}
struct Point {
double x, y;
Point(){}
Point(double x_, double y_) {
x = x_;
y = y_;
}
Point rotleft() {
return Point(-y, x);
}
Point operator + (const Point &b)const{
return Point(x + b.x, y + b.y);
}
Point operator - (const Point &b)const{
return Point(x - b.x, y - b.y);
}
Point operator /(const double &k)const{
return Point(x / k, y / k);
}
double operator ^(const Point &b)const{
return x * b.y - y*b.x;
}
double distance(Point p) {
return hypot(x - p.x, y-p.y);
}
}P[N];
struct Line {
Point s, e;
Line(){}
Line(Point s_, Point e_) {
s = s_;
e = e_;
}
Point crosspoint(Line v) {
double a1 = (v.e - v.s) ^ (s - v.s);
double a2 = (v.e - v.s) ^ (e - v.s);
return Point((s.x * a2 - e.x * a1)/ (a2 - a1), (s.y * a2 - e.y * a1)/ (a2 - a1));
}
};
struct circle {
Point p;
double r;
circle(){};
circle(Point p_, double r_) {
p = p_;
r = r_;
}
void get1(Point a, Point b, Point c) {
Line u = Line((a + b) / 2, ((a + b) / 2) + ((b - a).rotleft()));
Line v = Line((b + c) / 2, ((b + c) / 2) + ((c - b).rotleft()));
p = u.crosspoint(v);
r = p.distance(a);
}
bool relation(Point b) {
double dst = b.distance(p);
if(sgn(dst - r) == 0) return 1;
return 0;
}
};
int main() {
int T;
int n;
int x, y, z;
circle C;
int cnt = 0;
scanf("%d", &T);
while(T--) {
scanf("%d", &n);
for(int i = 1; i <= n; i++) scanf("%lf %lf", &P[i].x, &P[i].y);
if(n == 1) {
printf("%f %f %f\n", P[1].x - 1, P[1].y, 1.0);
continue;
}
if(n <= 4) {
printf("%.3f %.3f %.3f\n", (P[1].x + P[2].x) * 0.5, (P[1].y + P[2].y) *0.5,sqrt( (P[2].x - P[1].x) * (P[2].x - P[1].x) + (P[2].y - P[1].y) * (P[2].y - P[1].y) ) / 2);
continue;
}
for(int i = 1; ; i++) {
x = rand() % n + 1;
y = rand() % n + 1;
z = rand() % n + 1;
if( sgn((P[x] - P[y]) ^ (P[x] - P[z])) == 0) continue;
C.get1(P[x], P[y], P[z]);
cnt = 0;
for(int j = 1; j <= n; j++) {
if(C.relation(P[j])) cnt++;
}
if(cnt >= (n + 1) / 2) {
printf("%lf %lf %lf\n", C.p.x, C.p.y, C.r);
break;
}
}
}
return 0;
}
/*
7
1 1
1 0
1 -1
0 1
-1 1
0 -1
-1 0
*/