题目来源: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;
}