題目鏈接
題意
- 就是給你n個點,然後讓你求一個圓,使得至少有⌈2n⌉個點在圓上
題解
- 由於至少有一半的點在圓上,又因爲三個不再同一條直線上的點可以確定一個圓,那麼考慮隨機出這三個點,然後O(n)去check所有點是否在圓上,由於三個點都在構成答案的點集中的概率爲81,所以期望隨機次數爲8即可得到答案
- 打虛擬賽的時候由於最後纔想起來隨機,忘記特判n≤4的情況導致一直隨機而TLE,然後交了一發比賽就結束了QWQ
複雜度
代碼
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+10;
#define eps 1e-4
#define pi acos(-1.0)
int sgn(double k) {return k<-eps?-1:(k<eps?0:1);}
struct point{
double x,y;
point(double a=0,double b=0) {x=a;y=b;}
point operator*(double k) {return point(x*k,y*k);}
double operator*(point other) {return x*other.x+y*other.y;}
double operator^(point other) {return x*other.y-y*other.x;}
point operator/(double k) {return point(x/k,y/k);}
point operator+(point other) {return point(x+other.x,y+other.y);}
point operator-(point other) {return point(x-other.x,y-other.y);}
friend double len(point p) {return sqrt(p.x*p.x+p.y*p.y);}
friend point rotate(point p1,point p2,double a) {
point vec=p2-p1;
double xx=vec.x*cos(a)+vec.y*sin(a);
double yy=vec.y*cos(a)-vec.x*sin(a);
return point(p1.x+xx,p1.y+yy);
}
}p[maxn];
struct line{
point s,e;
line(){}
line(point a,point b) {s=a;e=b;}
friend point intersect(line l1,line l2) {
double k=((l2.e-l2.s)^(l2.s-l1.s)/((l2.e-l2.s)^(l1.e-l1.s)));
return l1.s+(l1.e-l1.s)*k;
}
};
struct circle{
point o;
double r;
circle() {}
circle(point a,point b,point c) {
point p1=rotate((a+b)/2,b,3*pi/2),p2=rotate((b+c)/2,c,3*pi/2);
o=intersect(line((a+b)/2,p1),line((b+c)/2,p2));
r=len(o-a);
}
};
int n;
int main() {
srand(998244353);
int t;scanf("%d",&t);
while(t--) {
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%lf %lf",&p[i].x,&p[i].y);
circle res;
if(n==1) {
printf("%.10lf %.10lf %.10lf\n",p[1].x,p[1].y,0);
continue;
}
else if(n<=4) {
printf("%.10lf %.10lf %.10lf\n",(p[1].x+p[2].x)/2,(p[1].y+p[2].y)/2,len(p[2]-p[1])/2);
continue;
}
for(;;) {
int x=rand()%n+1,y=rand()%n+1,z=rand()%n+1;
if(x==y||x==z||y==z||(sgn((p[y]-p[x])^(p[z]-p[x]))==0)) continue;
circle o=circle(p[x],p[y],p[z]);
int cnt=0;
for(int i=1;i<=n;i++) if(sgn(o.r-len(p[i]-o.o))==0) cnt++;
if(cnt>=(n+1)/2 &&fabs(o.o.x)<=1e9 &&fabs(o.o.y)<=1e9 &&fabs(o.r)<1e9) {res=o;break;}
}
printf("%.10lf %.10lf %.10lf\n",res.o.x,res.o.y,res.r);
}
}