牛客多校2 - Boundary(几何)

题目链接:点击查看

题目大意:给出 n 个点,需要我们选择一个经过原点的圆,使得这个圆经过尽可能多的点,输出最多可以经过多少个点

题目分析:n 的大小是 2000 ,显然支持 n * n 最多再加一个 log 的写法,因为三个不共线的点确定一个圆,圆上的一个点(原点)已经确定了,所以我们可以 O( n ) 枚举一下另一个定点 P,此时大概是这个样子

牛客多校2 - Boundary(几何)_第1张图片

最后 O( n ) 枚举点 A 时,此时不共线的三点已经可以确定一个圆了,换句话说,三个点就可以确定下来圆心的位置了,当点 P 和点 O 都确定下来后,枚举点 A 所得到的所有圆心的众数再加一,就是以此圆心做圆后可以经过的点的个数,利用map维护最大值就是答案了,找圆心的任务直接交给模板就好了

最后替出题人稍微解释一下吧,并没有卡 double 的精度,如果代码只过了 90% 或 95% 的样例的话,不妨看看下面两个特判:

1
1 0
ans=1

3
1 0
2 0
3 0
ans=1 

代码:
 

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
 
typedef long long LL;
 
typedef unsigned long long ull;
 
const int inf=0x3f3f3f3f;
 
const int N=2e3+100;
 
const double eps = 1e-6;
 
int sgn(double x){
    if(fabs(x) < eps)return 0;
    if(x < 0)return -1;
    else return 1;
}
 
struct Point{
    double x,y;
    Point(){}
    Point(double _x,double _y){
        x = _x;
        y = _y;
    }
    void input(){
        scanf("%lf%lf",&x,&y);
    }
    bool operator == (Point b)const{
        return sgn(x-b.x) == 0 && sgn(y-b.y) == 0;
    }
    bool operator < (Point b)const{
        return sgn(x-b.x)== 0?sgn(y-b.y)<0:xcnt;
        for(int j=i+1;j<=n;j++)
        {
            if(Line(point[i],point[j]).parallel(Line(point[i],Point(0,0))))
                continue;
            circle c(point[i],point[j],Point(0,0));
            ans=max(ans,++cnt[c.p]+1);
        }
    }
    printf("%d\n",ans);
 
 
 
 
 
 
 
    return 0;
}

 

你可能感兴趣的:(几何)