区间贪心 把可放置区域求出来 肯定是在区间的两端放置雷达 把区域由左坐标从小到大排列 进行比较 如果当前区间的左坐标比 上一大段可以一个雷达搞定的区间的最小右端点大 肯定要在上一个区间放雷达了,因为当前区间不能和上一个大段一个雷达 如果当前区间的左坐标没有超过上一个大段的最小右端点 则把当前区间加入上一个大段 并且更新上一个大段的最小右端点
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int n,d;
struct Node{
double x1,x2;
}node[2010];
bool cmp(Node a,Node b){
return a.x1<b.x1;
}
int main(){
int kase=1;
while(scanf("%d%d",&n,&d)==2&&n){
int temp1,temp2;
bool ok=0;
for(int i=0;i<n;i++){
scanf("%d%d",&temp1,&temp2);
node[i].x1=1.0*temp1-sqrt(d*d*1.0-1.0*temp2*temp2);
node[i].x2=1.0*temp1+sqrt(d*d*1.0-1.0*temp2*temp2);
if(d<temp2)ok=1;
}
if(ok){printf("Case %d: -1\n",kase++);continue;}
sort(node,node+n,cmp);
int cnt=1;
double p=node[0].x2;//可以一个雷达搞定的最小右端点
for(int i=1;i<n;i++){
if(node[i].x1>p)//不能和上一个大段一次性搞定则 在上一个大段放置一个雷达 并且把这一个区间作为下一个大段的起点
{
cnt++;
p=node[i].x2;
}
else if(node[i].x2<p)//可以和上一个大段一起搞定,则加入,并且维护这个大段的最小右端点
{
p=node[i].x2;
}
}
printf("Case %d: %d\n",kase++,cnt);
}
return 0;
}