2020牛客暑期多校训练营(第二场)B
题意:
给了n个点,让你自己随便定义圆心(圆心不要求是n个点的其中一个)和半径,要求这n个点有尽可能多的点在圆上,并且该圆经过坐标原点(0,0)。求满足的圆上的点最多有多少个。
思路:
三点确定一个圆,且必须过原点,只需用n^2的复杂度遍历枚举,并存下结果,处理完后对结果进行排序即可求出答案
代码如下:
#include<bits/stdc++.h>
using namespace std;
double X, Y;
struct Point
{
double x, y;
}a[2005];
void solve(Point a,Point b,Point c)
{
double fm1=2*(a.y-c.y)(a.x-b.x)-2(a.y-b.y)(a.x-c.x);
double fm2=2(a.y-b.y)(a.x-c.x)-2(a.y-c.y)(a.x-b.x);
if ( fm10 || fm20)
{
X=Y=1e18;
return;
}
double fz1=a.xa.x-b.xb.x+a.ya.y-b.yb.y;
double fz2=a.xa.x-c.xc.x+a.ya.y-c.yc.y;
X=(fz1(a.y-c.y)-fz2*(a.y-b.y))/fm1;
Y=(fz1*(a.x-c.x)-fz2*(a.x-b.x))/fm2;
}
vector<pair<double,double> > mp;
int main()
{
int n;
cin>>n;
for (int i=1;i<=n;i++)
cin>>a[i].x>>a[i].y;
for(int i=1;i<=n;i++){
for (int j=i+1;j<=n;j++){
solve({0, 0}, a[i], a[j]);
if (X==Y&&fabs(X-1e18)<1e-8)
continue;
mp.push_back({X,Y});
}
}
if(mp.size()==0){
putchar(‘1’);
return 0;
}
sort(mp.begin(),mp.end());
int ma = 1;
int num = 1;
pair<double,double> now=mp[0];
for(int i=1;i<mp.size();i++)
{
if(mp[i]==now) ++num;
else
{
now=mp[i];
ma=max(ma,num);
num=1;
}
ma=max(ma,num);
}
for(int i=1;i<=n;i++)
{
if (i*(i-1)==ma*2)
{
printf("%d",i);
return 0;
}
}
return 0;
}