题意:给你1e5个点,让你输出一个圆,满足至少n/2个点在圆上。
思路:因为至少有n/2个点在圆上,我们可以随机三个点。那么这三个点外接圆满足条件的概率至少为1/2*1/2*1/2=1/8,那么多随机几次就好了。注意特判n小于等于4的情况。
#include <bits/stdc++.h>
using namespace std;
struct Point {
double x;
double y;
} pt[100500];
struct Circle {
struct Point center;
double r;
} ans;
struct Traingle {
struct Point p[3];
};
double Dis(struct Point p, struct Point q) {
double dx=p.x-q.x;
double dy=p.y-q.y;
return sqrt(dx*dx+dy*dy);
}
double Area(struct Traingle ct) {
return
fabs((ct.p[1].x-ct.p[0].x)*(ct.p[2].y-ct.p[0].y)-(ct.p[2].x-ct.p[0].x)*(ct.p[1].y-ct.p[0].y))/2.0;
}
struct Circle CircumCircle(struct Traingle t) {
struct Circle tmp;
double a, b, c, c1, c2;
double xA, yA, xB, yB, xC, yC;
a = Dis(t.p[0], t.p[1]);
b = Dis(t.p[1], t.p[2]);
c = Dis(t.p[2], t.p[0]);
//根据 S = a * b * c / R / 4;求半径R
tmp.r = (a*b*c)/(Area(t)*4.0);
xA = t.p[0].x;
yA = t.p[0].y;
xB = t.p[1].x;
yB = t.p[1].y;
xC = t.p[2].x;
yC = t.p[2].y;
c1 = (xA*xA+yA*yA - xB*xB-yB*yB) / 2;
c2 = (xA*xA+yA*yA - xC*xC-yC*yC) / 2;
tmp.center.x = (c1*(yA - yC)-c2*(yA - yB)) / ((xA - xB)*(yA - yC)-(xA - xC)*(yA - yB));
tmp.center.y = (c1*(xA - xC)-c2*(xA - xB)) / ((yA - yB)*(xA - xC)-(yA - yC)*(xA - xB));
return tmp;
}
int main() {
int t;scanf("%d",&t);
while(t--) {
srand(time(NULL));
int n;scanf("%d",&n);
for(int i=0; i<n; i++) {
scanf("%lf%lf",&pt[i].x,&pt[i].y);
}
if(n==1)
{
printf("%lf %lf 1.00000\n",pt[0].x+1,pt[0].y);
continue;
}
else if(n<=4)
{
double r=sqrt((pt[0].x-pt[1].x)*(pt[0].x-pt[1].x)+(pt[0].y-pt[1].y)*(pt[0].y-pt[1].y))/2;
printf("%lf %lf %lf\n",(pt[0].x+pt[1].x)/2,(pt[0].y+pt[1].y)/2,r);
continue;
}
while(1) {
int a,b,c;
a=rand()%n;
b=rand()%n;
while(b==a)
{
b=rand()%n;
}
c=rand()%n;
while(c==a||c==b)
{
c=rand()%n;
}
Traingle tr;
tr.p[0]=pt[a];
tr.p[1]=pt[b];
tr.p[2]=pt[c];
Circle circle=CircumCircle(tr); //外接圆
int sum=0;
for(int i=0;i<n;i++)
{
if(abs(Dis(pt[i],circle.center)-circle.r)<=(1e-6))
{
sum++;
}
//printf("%lf %lf %lf %lf\n",circle.center.x,circle.center.y,circle.r,Dis(pt[i],circle.center));
//cout<<sum<<endl;
}
if(sum>=(n+1)/2)
{
printf("%lf %lf %lf\n",circle.center.x,circle.center.y,circle.r);
break;
}
}
}
return 0;
}