题目链接
Given n {n} n points in 2D plane. Considering all circles that the origin point ( 0 , 0 ) {(0, 0)} (0,0) is on their boundries, find the one with the maximum given points on its boundry. Print the maximum number of points.
The first line contains one integer n ( 1 ≤ n ≤ 2000 ) n~(1 \leq n \leq 2000) n (1≤n≤2000), denoting the number of given points.
Following {n}n lines each contains two integers x , y ( ∣ x ∣ , ∣ y ∣ ≤ 10000 ) x, y~(|x|,|y| \leq 10000) x,y (∣x∣,∣y∣≤10000), denoting a given point ( x , y ) {(x, y)} (x,y).
It’s guaranteed that the points are pairwise different and no given point is the origin point.
Only one line containing one integer, denoting the answer.
4
1 1
0 2
2 0
2 2
3
1.题解做法:
题解很容易懂,做起来很容易错
1.判断角度的个数不能直接用 m a p map map,会有精度问题,只能过 65%
2.如果存每一个角度判断还是有精度问题,此时离成功只差一步之遥了,能过 90%,那就是必须要 1 e − 10 1e^{-10} 1e−10 的精度
求角度直接套的板子,判断向量的方向直接用叉积即可,AC代码如下:
#include
using namespace std;
typedef long long ll;
const int N=2e3+5;
double ang[N*N],eps=1e-10;
struct point{
double x,y;
}p[N];
double cross(point a,point b,point c){
return (a.x-c.x)*(b.y-c.y)-(a.y-c.y)*(b.x-c.x);
}
double angle(point o,point s,point e)
{
double cosfi,fi,norm;
double dsx = s.x - o.x;
double dsy = s.y - o.y;
double dex = e.x - o.x;
double dey = e.y - o.y;
cosfi=dsx*dex+dsy*dey;
norm=(dsx*dsx+dsy*dsy)*(dex*dex+dey*dey);
cosfi /= sqrt( norm );
if (cosfi >= 1.0 ) return 0;
if (cosfi <= -1.0 ) return -3.1415926;
fi=acos(cosfi);
if (dsx*dey-dsy*dex>0) return fi;
return -fi;
}
int main(){
int n,ans=0;
point p0;
p0.x=p0.y=0;
scanf("%d",&n);
for(int i=0;i<n;i++){
scanf("%lf%lf",&p[i].x,&p[i].y);
}
for(int i=0;i<n;i++){
int sum=0,cnt=0;
for(int j=0;j<n;j++){
if(i==j) continue;
if(cross(p[i],p[j],p0)<0) ang[cnt++]=angle(p[j],p[i],p0);
}
sort(ang,ang+cnt);
double ANG=eps;
for(int i=0;i<cnt;i++){
if(fabs(ang[i]-ANG)<eps) sum++;
else{
ANG=ang[i];
sum=1;
}
ans=max(ans,sum);
}
}
printf("%d",ans+1);
return 0;
}
2.圆心公式,直接枚举两个点与圆点求圆心,圆心最多的就是答案,圆心公式直接套的板子,也可以手推,AC代码如下:
#include
using namespace std;
const int N=2e3+5;
double eps=1e-10;
map<pair<double,double>,int>m;
struct point{
double x,y;
}p[N];
double X,Y;
void Circle_center(point p1,point p2,point p3){
double a = p1.x - p2.x;
double b = p1.y - p2.y;
double c = p1.x - p3.x;
double d = p1.y - p3.y;
double e = ((p1.x * p1.x - p2.x * p2.x) + (p1.y * p1.y - p2.y * p2.y)) / 2.0;
double f = ((p1.x * p1.x - p3.x * p3.x) + (p1.y * p1.y - p3.y * p3.y)) / 2.0;
double det = b * c - a * d;
if (fabs(det) < eps) {
X=Y=0;
return ;
}
X = -(d * e - b * f) / det;
Y = -(a * f - c * e) / det;
return ;
}
int main(){
int n,ans=0;
point p0;
p0.x=p0.y=0;
scanf("%d",&n);
for(int i=0;i<n;i++)
scanf("%lf%lf",&p[i].x,&p[i].y);
for(int i=0;i<n;i++){
m.clear();
for(int j=i+1;j<n;j++){
if((p[i].x*p[j].y-p[j].x*p[i].y)==0) continue;
Circle_center(p0,p[i],p[j]);
m[{X,Y}]++;
ans=max(ans,m[{X,Y}]);
}
}
printf("%d",ans+1);
return 0;
}