题意
给了n个点,让你自己随便定义圆心(圆心不要求是n个点的其中一个)和半径,要求这n个点有尽可能多的点在圆上,并且该圆经过坐标原点(0,0)。求满足的圆上的点最多有多少个。

思路
n是2e3,复杂度应该要小于n^3。我们知道最少三点可以确定一个圆。因为圆要求经过原点(0,0),所以考虑n^2枚举两个点,这样子就有三个点了,计算出三个点形成的圆的圆心坐标(注意三点共线的情况 那么肯定不存在圆 使得三点在一个圆上)
用vector保存下来这些圆心坐标。
处理完后,对圆心坐标sort一下,判断有多少个圆心坐标是一样的。

刚开始写的是map<pair<double,double>,int> 去存 ,一直TLE,只能过70%数据,所以就直接sort计算相同个数了

如果vector中,圆心个数为0,也就是所有点都在一条线上,那么直接输出1
因为两点可以确定无数个圆,选n个点中的一个都能和坐标原点形成任意一个圆

否则,在暴力枚举的两个点中,我们是组合数进行选取的,也就是n个点选取2个
图片说明
其中ma是指出现最多的圆心坐标的次数
那么直接枚举1到n满足上述式子的就是答案

#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 (fm1 == 0 || fm2 == 0)
    {
        X = Y = 1e18;
        return;
    }
    double fz1=a.x * a.x - b.x * b.x + a.y * a.y - b.y * b.y;
    double fz2=a.x * a.x - c.x * c.x + a.y * a.y - c.y * c.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;
    scanf("%d", &n);
    for (int i = 1; i <= n; i++)  scanf("%lf%lf", &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;
}