题:https://ac.nowcoder.com/acm/contest/5667/B
题意:给出n个二维平面点,问最多有多少个点和原点(0,0)同时在同一个圆的边上
分析:由三点确定圆心n^2枚举出所有圆心,最后求众数即可;
由于我们n^2枚举出来的圆心个数是由重复部分的,因为假设1,2,3,4点在同一个圆x上,而我们枚举1 时x的圆心的贡献是3,而枚举2时x的圆心贡献是2,以此类推就是一个1~n的和,所以只要排序后累计个数即可
#include<bits/stdc++.h> using namespace std; #define pb push_back #define MP make_pair #define eps 1e-10 typedef long long ll; const int mod=1e9+7; const int M=2e5+5; const int N=2e6+6; const int inf=0x3f3f3f3f; const ll INF=1e18; struct node{ double x,y; node(double X=0,double Y=0):x(X),y(Y){}; }p[M],b[N]; double X,Y,R; //过三点求圆心坐标 node waixin(node a,node b,node c){ double a1 = b.x - a.x, b1 = b.y - a.y, c1 = (a1*a1 + b1*b1)/2; double a2 = c.x - a.x, b2 = c.y - a.y, c2 = (a2*a2 + b2*b2)/2; double d = a1*b2 - a2*b1; return node(a.x + (c1*b2 - c2*b1)/d, a.y + (a1*c2 -a2*c1)/d); } int main(){ int n; scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%lf%lf",&p[i].x,&p[i].y); node O={0,0}; int tot=0; for(int i=1;i<=n;i++) for(int j=i+1;j<=n;j++){ if(fabs(p[i].x*p[j].y-p[j].x*p[i].y)>eps){ node tmp=waixin(p[i],p[j],O); b[tot++]=tmp; } } if(tot==0) return printf("1"),0; sort(b,b+tot,[&](node A,node B){ if(fabs(A.x-B.x)<eps) return A.y-B.y<eps; else return A.x-B.x<eps; }); int countt=1,maxx=1; for(int i=0;i<tot-1;i++) if(fabs(b[i].x-b[i+1].x)<eps&&fabs(b[i].y-b[i+1].y)<eps) countt++,maxx=max(maxx,countt); else countt=1; int sum=maxx*2; for(int i=1;i<=n;i++) if(i*(i-1)==sum) return printf("%d",i),0; return 0; }