求出每个点在x上以半径能覆盖的区域,然后对每个区域的右边从小到大排序。运用贪心即可。
注意需要判断半径是否为负。
/*
poj 1328
*/
#include <stdio.h>
#include <utility>
#include <string.h>
#include <math.h>
#include <algorithm>
using namespace std;
bool cmp(pair<double ,double> a,pair<double ,double> b)
{
if(a.second<=b.second)
return true;
else
return false;
}
int main(int argc, char const *argv[])
{
// freopen("input","r",stdin);
pair<double ,double> a[1200];
int n,d;
int k=0;
while(scanf("%d%d",&n,&d),n || d)
{
// printf("%d %d\n",n,d );
k++;
int num=0;
memset(a,false,sizeof(a));
int x,y;
int status=1;
for(int i=0;i<n;i++)
{
scanf("%d%d",&x,&y);
// printf("%d %d\n",x,y );
if(d<0 || d*d-y*y<0)
status=0;
else
{
a[i].first=x-sqrt(d*d-y*y);
a[i].second=x+sqrt(d*d-y*y);
}
}
if(status==0)
{
printf("Case %d: %d\n",k,-1 );
continue;
}
sort(a,a+n,cmp);
// for (int i = 0; i < n; ++i)
// {
// printf("%lf %lf\n",a[i].first,a[i].second );
// }
int v=0;
while(v<n)
{
int t=v;
num++;
// printf("%d\n",num );
for(int i=v+1;i<n;i++)
if(a[i].first<=a[t].second)
v=i;
else
break;
v++;
}
printf("Case %d: %d\n", k,num);
}
return 0;
}