hoj 1633 Transmitters //poj 1106 Transmitters
/*
题目:
给出一个点的坐标以及以它为半径的半圆,现给出所有的零散的点的坐标,问最多半圆能覆盖的点的数目
分析:
先预处理完所有的点到圆心的距离,然后排序得到所有可以在整个圆上的点,再枚举其中一个点作为
半圆的一条半径,再用叉积分>=0和<=0分成两类,判断这两个与答案的最大值,更新后输出答案
*/
#include <iostream>
#include <cmath>
#include <cstdio>
#include <algorithm>
using namespace std;
#define MAXN 160
#define esp 1e-8
struct point//点的结构
{
int x,y;
}p[MAXN];
struct Dist
{
double dis;
int id;
friend bool operator <(Dist a,Dist b)
{
return a.dis<b.dis||(b.dis==a.dis&&a.id<b.id);
}
}dist[MAXN];
int n;
double r;
point d;
int dcmp(double x)//零
{
if(abs(x)<=esp)return 0;
return x>0?1:-1;
}
double dis(point a,point b)//距离的平方
{
return 1.0*(a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);
}
double det(point a,point b,point o)//叉积函数
{
return (a.x-o.x)*(b.y-o.y)-(b.x-o.x)*(a.y-o.y);
}
void input()//输入函数
{
cin>>n;
r *= r;
for(int i=0;i<n;i++)
{
scanf("%d%d",&p[i].x,&p[i].y);
dist[i].dis = dis(d,p[i]);
dist[i].id = i;
}
sort(dist,dist+n);//对距离进行排序
int top = n;
for(int i=0;i<n;i++)//找到最远的符合的点
{
if(dist[i].dis>r)
{
top = i;
break;
}
}
int ans = 0;
double t;
for(int i=0;i<top;i++) //枚举该点所在的半圆,有多少个点在里面
{
int cur = 0;
for(int j=0;j<top;j++)
{ //判断是否在半圆其实可以用叉积判断,所有的<=0的点均属同一个半圆
t = det(p[dist[i].id],p[dist[j].id],d);
if(t<=0)
cur++;
}
ans = max(cur,ans); //更新一下
cur = 0;
for(int j=0;j<top;j++) //另外的一面同样更新一下
{
t = det(p[dist[i].id],p[dist[j].id],d);
if(t>=0)
cur++;
}
ans = max(cur,ans);
}
cout<<ans<<endl;
}
int main()
{
freopen("sum.in","r",stdin);
freopen("sum.out","w",stdout);
while(cin>>d.x>>d.y>>r,r>=0)
{
input();
}
return 0;
}