这是一道区间贪心的题目,对于这道题,由于岛屿的位置在坐标轴上是确定的,而雷达的位置及数量则无法确定,因此我们可以根据岛屿来确定雷达的位置及数量。首先,我们可以根据岛屿的位置以及雷达的半径来确定覆盖该岛屿的雷达的位置区间,如下图:
我们可以以岛屿为圆心,雷达的半径为半径画圆,则其与x轴有两个交点分别为a、b,雷达在[a, b]区间任意位置都能够覆盖当前的岛屿,因此我们可以将岛屿的位置处理成a、b两个x的坐标:
#include<iostream>
#include<algorithm>
#include<cmath>
#define min(a, b) (a<b)?a:b
using namespace std;
const int N = 1000 + 10;
struct Interval{
double left;
double right;
};
Interval arr[N];
bool cmp(Interval x, Interval y){
return x.left < y.left;
}
int main(){
int n, d, x, y;
int caseNumber = 1;
while(scanf("%d%d", &n, &d) != EOF){
if(n == 0&&d == 0) break;
bool flag = true;
for(int i = 0;i < n;i++){
scanf("%d%d", &x, &y);
if(y > d) flag = false; //y坐标大于d,则说明雷达无论如何都无法覆盖该岛屿
else{
arr[i].left = x - sqrt(d * d - 1.0 * y * y);
arr[i].right = x + sqrt(d * d - 1.0 * y * y);
}
}
if(!flag) printf("Case %d: -1\n", caseNumber++);
else{
sort(arr, arr + n, cmp); //根据左端点进行排序
int sum = 1;
double current = arr[0].right;
for(int i = 1;i < n;i++){
if(arr[i].left <= current) //若雷达可以覆盖该岛屿,则取右端点的最小值
current = min(current, arr[i].right);
else{ //若雷达不可以覆盖该岛屿,则需要新建一个雷达
current = arr[i].right;
sum++;
}
}
printf("Case %d: %d\n", caseNumber++, sum);
}
}
return 0;
}