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