此题类似数轴上有N个点,用多少单位长度线可以覆盖,也类似活动选择问题。属于比较基础的贪心算法。
思路:把点转换为x轴上线段覆盖的问题。
如P2(-3, 1),转换成x轴为-3 - sqrt(d * d - 1 * 1) 和 -3 + sqrt(d * d - 1 * 1),左右两个点。
对左点进行排序,判断各个线段之间的重叠情况,判断需要几个雷达。
细节见代码。
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
typedef struct _node {
double left;
double right;
}Node;
Node point[1001];
int n, d;
int cmp(const void *a, const void *b)
{
return (*(Node *)a).left >= (*(Node *)b).left ? 1 : -1;
}
int greedy() {
int result = 1;
qsort(point, n, sizeof(Node), cmp);
double num = point[0].right;
for (int i = 1; i < n; ++i) {
if (point[i].left > num) { // 不想交
++result;
num = point[i].right;
} else {
if (point[i].right < num) // 相容
num = point[i].right;
}
}
return result;
}
int main()
{
int x, y, flag, num = 0;
while (scanf("%d%d", &n, &d) != EOF) {
flag = 1;
num++;
if (n + d == 0)
break;
for (int i = 0; i < n; ++i) {
scanf("%d%d", &x, &y);
if (y > d)
flag = 0;
double l = sqrt(double(d * d - y * y));
point[i].left = x - l;
point[i].right = x + l;
}
if (!flag)
printf("Case %d: -1\n", num);
else
printf("Case %d: %d\n", num, greedy());
}
}