原题链接
考察:计算几何
思路:
  已知两点和半径可以确定一个圆,最优解的圆一定可以偏移直到相交于两点.至于怎么求圆心看 GO
  求正反两遍,求不用讨论谁上下问题.

Code

#include <iostream> 
#include <cstring>
#include <cmath>
using namespace std;
const double eps = 1e-6;
const int N = 110;
int n,ans;
double r;
struct Point{
	double x,y;
	Point(){}
	Point(double a,double b){
		this->x = a;
		this->y = b;
	}
}point[N];
double Dist(Point a,Point b)
{
	return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
int get(double x,double y)
{
	Point m = Point(x,y);
	int ans = 0;
	for(int i=1;i<=n;i++)
	{
		double d = Dist(point[i],m);
		if(d-r<=eps) ans++; 
	}
	return ans;
}
int main()
{
	freopen("in.txt","r",stdin);
	scanf("%lf%d",&r,&n);
	for(int i=1;i<=n;i++) scanf("%lf%lf",&point[i].x,&point[i].y);
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=n;j++)
		  if(j!=i)
		  {
		  	double dist = Dist(point[i],point[j]);
		  	if(dist>2*r) continue;
		  	double ang = atan2(point[j].x-point[i].x,point[i].y-point[j].y);
		  	double d = sqrt(r*r-dist*dist/4);
		  	double xm = (point[i].x+point[j].x)/2,ym = (point[i].y+point[j].y)/2;
		  	double dx = xm+d*cos(ang),dy = ym+d*sin(ang);
		  	ans = max(get(dx,dy),ans);
		  }
	}
	printf("%d\n",max(ans,1));
	return 0;
}