Geometry Problem
Alice is interesting in computation geometry problem recently. She found a interesting problem and solved it easily. Now she will give this problem to you
You are given N distinct points (Xi,Yi) on the two-dimensional plane. Your task is to find a point P and a real number R, such that for at least ⌈N/2⌉ given points, their distance to point P is equal to R.
N<=1e5
题意: 给你N个点,求出某个圆上至少有一半的点在上面
思路: 因为题面已经保证至少有一半点在某个圆上,我们可以随机取三个点,至少有1/8的概率同时取到三个点就是那一半的点,而三点可以确定一个圆,故一般来说大概8次有1次可以找到那个圆,注意需要注意点数小于4的时候特判掉就行
三点确定一个圆的公式与模板,记得需要限制条件保证三点不在一条直线上
已知三点求圆心与半径模板
double dis2(int a)
{
return sqrt((p[a].x-x)*(p[a].x-x)+(p[a].y-y)*(p[a].y-y));
}
void cal(int a,int b,int c)//求外心
{
double a1 = p[b].x - p[a].x, b1 = p[b].y - p[a].y, c1 = (a1*a1 + b1*b1)/2;
double a2 = p[c].x - p[a].x, b2 = p[c].y - p[a].y, c2 = (a2*a2 + b2*b2)/2;
double d = a1 * b2 - a2 * b1;
x = p[a].x + (c1*b2 - c2*b1)/d,y = p[a].y + (a1*c2 - a2*c1)/d;
r = dis2(a);
}
#include
typedef long long ll;
using namespace std;
const int N=1e5+5;
double x,y,r;
int n;
struct node
{
double x,y;
}p[N];
double dis(int p1,int p2)
{
return sqrt((p[p1].x-p[p2].x)*(p[p1].x-p[p2].x)+(p[p1].y-p[p2].y)*(p[p1].y-p[p2].y));
}
double dis2(int a)
{
return sqrt((p[a].x-x)*(p[a].x-x)+(p[a].y-y)*(p[a].y-y));
}
void cal(int a,int b,int c)//求外心
{
double a1 = p[b].x - p[a].x, b1 = p[b].y - p[a].y, c1 = (a1*a1 + b1*b1)/2;
double a2 = p[c].x - p[a].x, b2 = p[c].y - p[a].y, c2 = (a2*a2 + b2*b2)/2;
double d = a1 * b2 - a2 * b1;
x = p[a].x + (c1*b2 - c2*b1)/d,y = p[a].y + (a1*c2 - a2*c1)/d;
r = dis2(a);
}
bool check(int p1,int p2,int p3)
{
cal(p1,p2,p3);
int cnt=0;
for(int i=0;i<n;i++)
{
if(fabs(dis2(i)-r)<1e-8)
{
cnt++;
}
}
if(2*cnt>=n)
{
return 1;
}
return 0;
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
for(int i=0;i<n;i++)
{
scanf("%lf%lf",&p[i].x,&p[i].y);
}
if(n==1||n==2)
{
printf("%.6f %.6f %.6f\n",p[0].x,p[0].y-1,1.0);
continue;
}
else if(n<=4)
{
double x1=p[0].x+p[1].x,y1=p[0].y+p[1].y;
double r=dis(0,1);
printf("%.6f %.6f %.6f\n",x1/2,y1/2,r/2);
continue;
}
while(1)
{
int p1=rand()%n,p2=rand()%n,p3=rand()%n;
if(p1==p2||p2==p3||p1==p3)
continue;
int flag=check(p1,p2,p3);
if(flag)
{
printf("%.6f %.6f %.6f\n",x,y,r);
break;
}
}
}
return 0;
}