平面上有n个点。给你一个半径为r的圆,问最多能覆盖多少个点(圆周上的点能够被覆盖)
输入格式
本题有多组测试数据,请处理到EOF 每组数据第一行有两个整数n,r,表示平面上点的个数和圆的半径。 0<=n<=200,1<=r<=1000
接下去n行每行有两个整数xi,yi,分别为n个点的坐标,-10000<=xi,yi<=10000
输出格式
对每组输入,输出这个圆最多能覆盖多少个点
样例输入
4 1 0 0 0 1 1 0 1 1
样例输出
4
当n=0时,答案是0;
当n=1时,答案是1;
当n>=1&&n<=200时,用枚举每两个点构造圆的方法,找圆最多能覆盖的点的个数。
#include<iostream>
#include<math.h>
#include<algorithm>
using namespace std;
#define xsd 1e-8
double ctrx1,ctrx2,ctry1,ctry2;
double distance(double x1,double y1,double x2,double y2) {
return sqrt(pow(x1-x2,2)+pow(y1-y2,2));
}
void sCenter(double x1,double y1,double x2,double y2,int r) {
double dispq = distance(x1,y1,(x1+x2)/2.0,(y1+y2)/2.0);
double dis = sqrt(r*r - dispq*dispq);
double theta = atan2(x1-x2,y2-y1);//这句很重要
ctrx1 = (x1+x2)/2.0 + dis*cos(theta);
ctry1 = (y1+y2)/2.0 + dis*sin(theta);
ctrx2 = x1+x2-ctrx1;
ctry2 = y1+y2-ctry1;
}
int main() {
int n,r;
while(cin>>n>>r) {
int x[n],y[n];
for (int i=0; i<n; i++)
cin>>x[i]>>y[i];
int ans = 0;
if(n!=0) {
ans=1;
for (int i=0; i<n; i++) {
for (int j=i+1; j<n; j++) {
if (distance(x[i],y[i],x[j],y[j])> 2.0*r+xsd) continue;
int cnt1 = 0;
int cnt2 = 0;
sCenter(x[i],y[i],x[j],y[j],r);
for(int k=0; k<n; k++) {
if(distance(ctrx1,ctry1,x[k],y[k])<1.0*r+xsd) ++cnt1;
if(distance(ctrx2,ctry2,x[k],y[k])<1.0*r+xsd) ++cnt2;
}
int cnt = max(cnt1,cnt2);
ans = max(cnt,ans);
}
}
}
cout<< ans<< endl;
}
return 0;
}