题目大意
假设海岸线是无线长的直线,现在海上有很多小岛,坐标已知,雷达的覆盖半径已知,求解最少需要多少个雷达能够覆盖所有小岛,若不能,输出-1。
解题思想
我们可以根据小岛的纵坐标和雷达覆盖的半径求出对于每一个小岛,雷达能够摆放的最远距离,使得小岛刚好能够被雷达覆盖到。假设x,y为小岛的坐标,d为雷达的覆盖半径,则左边最远距离为(x-sqrt(d*d - y*y)),右边最远距离为(x+sqrt(d*d - y*y)),然后按照右最远距离排序,若当前小岛的左最远距离在雷达位置的右边,那么该雷达就无法覆盖到此小岛,此时需要再增加一个雷达,然后将雷达的位置更新为当前小岛的右最远距离处。基本的贪心问题,需要将坐标处理一下。
代码
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#define INF 100000000
using namespace std;
struct Node
{
double start, end;
};
Node num[1010];
bool cmp(Node a, Node b)
{
return a.end < b.end;
}
int main()
{
int N, k = 1;
double d;
bool flag;
while(scanf("%d%lf", &N, &d), N||d)
{
double x, y;
flag = true;
for(int i = 0; i < N; i++)
{
scanf("%lf%lf", &x, &y);
if(!flag) continue;
if(y > d)
{
flag = false;
continue;
}
num[i].start = x - sqrt(d * d - y * y); //左最远距离
num[i].end = x + sqrt(d * d - y * y); //右最远距离
}
printf("Case %d: ", k++);
if(!flag)
{
printf("-1\n");
continue;
}
sort(num, num+N, cmp);
int ans = 0;
double temp = -INF;
for(int i = 0; i < N; i++)
{
if(temp < num[i].start)
ans++, temp = num[i].end; //若当前小岛的左最远距离在雷达的右边
} //则需要再添加一个新的雷达
printf("%d\n", ans);
}
return 0;
}