题意:
有n个在x轴上方的小岛的坐标,还给出雷达的范围,现在要求在x轴上放尽量少的雷达使岛都被覆盖到,问最少数量。
题解:
贪心。确定每个岛在x轴上的映射范围(此范围内有雷达则能扫到小岛),然后按右界排序,然后类似于单调队列(当然要水多了),把雷达尽量往右放。
细节:
注意一:
雷达不用非得在整点上,别被示意图骗了。
注意二:
如果数据有误输出-1
一、某些点扫不到
二、某些点在x轴下面
三、d<0
代码:
#include <cmath>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define N 1050
#define inf 0x3f3f3f3f
using namespace std;
int n,d;
struct KSD
{
int x,y;
double l,r;
bool init()
{
int temp=d*d-y*y;
if(temp<0)return 1;
l=x-sqrt(temp);
r=x+sqrt(temp);
return 0;
}
bool operator < (const KSD &a)const
{return r<a.r;}
}s[N];
int main()
{
// freopen("test.in","r",stdin);
int i,t=0,flag;
while(scanf("%d%d",&n,&d),n||d)
{
printf("Case %d: ",++t);
flag=0;
if(d<0)flag=1;
for(i=1;i<=n;i++)
{
scanf("%d%d",&s[i].x,&s[i].y);
if(s[i].y<0||s[i].init())flag=1;
}
if(flag)
{
puts("-1");
continue;
}
sort(s+1,s+n+1);
double now=-999999999.9;
int ans=0;
for(i=1;i<=n;i++)
{
if(s[i].l<=now)continue;
now=s[i].r;
ans++;
}
printf("%d\n",ans);
}
return 0;
}