题目来源:https://ac.nowcoder.com/acm/contest/5667/B
题目大意:给你n个点,找出一个过原点的圆,使得这个圆经过最多的点。
做题历程:比赛的时候这题是由队友负责的,过了一会儿就给他过了,但是具体情况我没怎么亲身去感受,所以还是别人的,现在自己亲自感受一下。
解题目主要思路:三个不共线点确定一个圆。因为原点已经确定了,所以只需要在给定的点中找两个点,
找到一个点,然后再找到一个点(就是枚举了),然后通过推出来的三点确定一个圆的圆心,再来判断其它点有多上个在这个圆上。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<double,double> P;
#define N 2010
ll x[N],y[N];
map<P,int>cmp;
int n;
bool check(ll x1,ll y1,ll x2,ll y2)
{
return x1*y2==x2*y1; //防止三点共线
}
void f1()
{
int ans=0;
for(int i=1; i<=n; ++i) //大枚举
{
cmp.clear();
for(int j=i+1; j<=n; ++j)
{
if(check(x[i],y[i],x[j],y[j]))
continue;
ll a1=y[i]*(x[j]*x[j]+y[j]*y[j])-y[j]*(x[i]*x[i]+y[i]*y[i]);
ll a2=y[i]*x[j]-y[j]*x[i];
ll b1=x[i]*(x[j]*x[j]+y[j]*y[j])-x[j]*(x[i]*x[i]+y[i]*y[i]);
ll b2=y[j]*x[i]-y[i]*x[j];
ans=max(ans,++cmp[P(1.0*a1/a2,1.0*b1/b2)]);//为每一个圆心在上面的点数作比较 ,将最大的更新。
}
}
cout<<ans+1<<endl;//别忘了最初多选的一个点
return;
}
int main()
{
cin>>n;
for(int i=1; i<=n; i++)
{
cin>>x[i]>>y[i]; //把点存到一个数组里面
}
f1();
return 0;
}
京公网安备 11010502036488号