以每个岛屿为中心 以d为半径做圆 圆与x轴相交部分即是想要覆盖这个岛屿时雷达位置的可选区间
贪心策略就是以每个区间的右端点向右扫(记为p) 即假设雷达站建在这个区间的最右端 在满足覆盖当前岛屿的条件下 尽量为覆盖其后岛屿创造有利条件
如果p够不到下一个区间 就说明需要新建雷达站 更新p值
如果p能够到 就看当前这个区间的右端点是不是比p要小
如果比p小 考虑到我们要把这个雷达站建在p处 当前这个岛屿就无法覆盖 所以为了照顾当前岛屿 要把雷达站建的更近一些 即把p更新为当前岛屿区间的右端点(这点容易忽略)
否则继续扫
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
using namespace std;
struct node
{
double l;
double r;
};
node line[1010];
double r;
int n;
bool cmp(node n1,node n2)
{
if(n1.l==n2.l)
{
return n1.r>n2.r;
}
else
{
return n1.l<n2.l;
}
}
int main()
{
double x,y,p;
int cas,i,j,flag,ans;
cas=1;
while(scanf("%d%lf",&n,&r)!=EOF)
{
if(n==0&&r==0) break;
flag=1;
for(i=1;i<=n;i++)
{
scanf("%lf%lf",&x,&y);
if(y>r) flag=0;
line[i].l=x-sqrt(r*r-y*y);
line[i].r=x+sqrt(r*r-y*y);
}
if(flag==0)
{
printf("Case %d: -1\n",cas++);
continue;
}
sort(line+1,line+n+1,cmp);
p=line[1].r;
ans=1;
for(i=2;i<=n;i++)
{
if(line[i].l>p)
{
p=line[i].r;
ans++;
}
else if(line[i].r<p)
{
p=line[i].r;
}
}
printf("Case %d: %d\n",cas++,ans);
}
return 0;
}