题意
给你一条直线,直线两端点为(0,0)和(a,b),在直线上找一圆心,求能覆盖最多的点为多少
Sample input
7 5 0 1
-1 -1
1 -1
0 0
2 3
3 4
10 10
2 12
Sample output
5
看的是这位大佬的
#include <cstdio>
#include <iostream>
#include <cmath>
#include <utility>
#include <vector>
#include <algorithm>
#define eps 1e-8
#define N_MAX 300005
using std::pair;
int n,ans,res;
double r,a,b;
int sign(double x){
if(fabs(x) < eps)return 0;
if(x < 0)return -1;
return 1;
}
struct Node{
double x,y;
int c;
Node(double x = 0,double y = 0,int c = 0):x(x),y(y),c(c){}
};
bool cmp(Node _a,Node _b){
if(sign(_a.x - _b.x) == 0 && sign(_a.y - _b.y) == 0 )return _a.c > _b.c;
if(sign(_a.x - _b.x) == 0)return _a.y < _b.y;
return _a.x < _b.x;
}
std::vector <Node> vec;
struct Point{
double x,y;
Point(double x = 0,double y = 0):x(x),y(y){}
Point operator+(Point a){
return Point(x + a.x,y + a.y);
}
Point operator-(Point a){
return Point(x - a.x,y - a.y);
}
Point operator*(double t){
return Point(x * t,y * t);
}
Point operator/(double t){
return Point(x / t,y / t);
}
double cross(Point a){
return x * a.y - a.x * y;
}
double dot(Point a){
return a.x * x + a.y * y;
}
double lenth(){
return sqrt(x * x + y * y);
}
}point[N_MAX];
struct Line{
Point a,b;
Line(){}
Line(Point a,Point b){
this->a = a;
this->b = b;
}
}line;
Point GetPointForLine(Line X,Line Y){ // 算直线交点
Point v = X.a - X.b;
Point w = Y.a - Y.b;
Point u = X.a - Y.a;
double base = (w.cross(u)) / (v.cross(w));
return X.a + v * base;
}
double DistanceForLine(Point P,Line X){ // 算点到直线的距离
Point vp = X.b - X.a,vq = P - X.a;
return fabs(vp.cross(vq))/vp.lenth();
}
pair<Point,Point> PointWithCircleAndLine(Point o,Line X){ // 求圆与直线的交点
Point o2 = o;
o2.x += X.a.y - X.b.y;
o2.y += X.b.x - X.a.x;
o2 = GetPointForLine(Line(o,o2),X);
double base = sqrt(r * r - (o2 - o).lenth() * (o2 - o).lenth());
Point e = (X.b - X.a) / (X.b - X.a).lenth();
return std::make_pair(o2 - e * base,o2 + e * base);
}
int main(int argc,char *argv[]){
scanf("%d %lf %lf %lf",&n,&r,&a,&b);
line.a = Point(0,0);
line.b = Point(a,b);
for(int i = 1;i <= n;i++){
scanf("%lf %lf",&point[i].x,&point[i].y);
if(DistanceForLine(point[i],line) <= r){
pair<Point,Point> q = PointWithCircleAndLine(point[i],line);
Node p1 = Node(q.first.x,q.first.y,1);
Node p2 = Node(q.second.x,q.second.y,-1);
if(p1.x > p2.x){
p1.c = -1;
p2.c = 1;
}
else if(sign(p1.x - p2.x) == 0 && p1.y > p2.y){
p1.c = -1;
p2.c = 1;
}
vec.emplace_back(p1);
vec.emplace_back(p2);
}
}
std::sort(vec.begin(),vec.end(),cmp);
for(auto i:vec){
//printf("%.2lf %.2lf\n",i.x,i.y);
res += i.c;
ans = std::max(res,ans);
}
printf("%d\n",ans);
return 0;
}