每组实例给出一个圆心,半径r(半径为负值时结束),然后是若干个点(最多150个),求以所给圆心和半径,画半圆,最多能覆盖多少个所给点集中的点。
先筛选出所给点集中哪些是在圆内的点,然后依次以这些点和圆心连线分割圆,统计半圆内点数,求出最大值
上代码
#include<stdio.h>
#include<string.h>
#include<math.h>
#define N 160
double dis(double x1,double y1,double x2,double y2)//dis()函数返回的不是距离,是距离的平方,因为开方会丧失精度
{
return (x1-x2)*(x1-x2)+(y1-y2)*(y1-y2);
}
double xmult(double x1,double y1,double x2,double y2,double x,double y)
//点a(x1,y1)和点b(x2,y2)分别与原点o(x,y)构成向量(x1-x,y1-y)和(x2-x,y2-y)
//叉乘值为正表示向量 oa 在 ob 的顺时针pi范围内
//叉乘值为负时表示向量 oa 在 ob 的逆时针pi范围内
{
return (x1-x)*(y2-y)-(x2-x)*(y1-y);
}
int main()
{
int i,j,n,a,max,in[N];
double xo,yo,r,x[N],y[N];
while(scanf("%lf%lf%lf",&xo,&yo,&r),r>=0)
{
scanf("%d",&n);
r=r*r; //注意是平方
memset(in,0,sizeof(in));
for(i=1;i<=n;i++)
{
scanf("%lf%lf",&x[i],&y[i]);
if(dis(x[i],y[i],xo,yo)<=r)
in[i]=1;
}
max=0;
for(i=1;i<=n;i++)
{
if(in[i])
{
a=0;
for(j=1;j<=n;j++)
{
if(in[j] && xmult(x[i],y[i],x[j],y[j],xo,yo)>=0)
a++;
}
if(a>max) max=a;
}
}
printf("%d\n",max);
}
return 0;
}