题目大意:
给定n个点,然后确定一个过原点的圆,要使这n个点尽可能多的存在与圆上,最后输出最多的存在于圆上的点的个数
题目思路:
三点确定一个圆,我们已知这个圆必定经过原点,所以再依次利用三点求圆心的公式枚举每两个点与原点(三点不共线)确定的圆心,最后选择确定次数最多的圆心构成的圆
#include<iostream>
#include<map>
#include<algorithm>
#include<cmath>
#define ll long long
using namespace std;
struct zb
{
double x,y;
}p[2005];
map<pair<double,double>,int>mp;
int ans=0;
void solve(zb a,zb b,zb c)
{
double f1,f2,f3,f4,f5,f6,f7,f8;
f1=a.x*a.x-b.x*b.x+a.y*a.y-b.y*b.y;
f2=a.y-c.y;
f3=a.x*a.x-c.x*c.x+a.y*a.y-c.y*c.y;
f4=a.y-b.y;
f5=2.0*(a.y-c.y)*(a.x-b.x)-2*(a.y-b.y)*(a.x-c.x);
f6=a.x-c.x;
f7=a.x-b.x;
f8=2.0*(a.y-b.y)*(a.x-c.x)-2*(a.y-c.y)*(a.x-b.x);
double x=(f1*f2-f3*f4)/f5;
double y=(f1*f6-f3*f7)/f8;
mp[{x,y}]++;
ans=max(ans,mp[{x,y}]);
}
int main()
{
int n;
cin>>n;
for(int i=0;i<n;i++)
cin>>p[i].x>>p[i].y;
for(int i=0;i<n;i++)
{
mp.clear();
for(int j=i+1;j<n;j++)
{
if(p[i].x*p[j].y==p[i].y*p[j].x) //防止三点共线
continue;
solve({0.0,0.0},p[i],p[j]);
}
}
cout<<ans+1<<endl;
return 0;
}