题目链接
http://poj.org/problem?id=1328
分析
贪心,转化为选最少的点覆盖所有区间。
将区间按右端点升序排序,依次考虑每个区间,若不能覆盖,则在区间右端点加雷达。
很容易理解,选择右端点是最优的。
AC代码
#include <cstdio>
#include <cmath>
#include <algorithm>
using namespace std;
inline int read() {
int num = 0, flag = 1;
char c = getchar();
while (c < '0' || c > '9') {
if (c == '-') flag = -1;
c = getchar();
}
while (c >= '0' && c <= '9')
num = num * 10 + c - '0', c = getchar();
return flag * num;
}
const int maxn = 1e3 + 5;
struct Segment {
double l, r;
bool operator < (const Segment& rhs) const {
return r < rhs.r;
}
} segment[maxn];
int main() {
int n, d, id = 0;
while (scanf("%d%d", &n, &d) == 2 && n && d) {
int flag = 1, cnt = 0;
double last;
for (int i = 1; i <= n; ++i) {
int x = read(), y = read();
if (y > d) {
flag = 0;
continue;
}
double dx = sqrt(d * d - y * y);
segment[i].l = x - dx, segment[i].r = x + dx;
}
printf("Case %d: ", ++id);
if (!flag) {
printf("-1\n");
continue;
}
sort(segment + 1, segment + n + 1);
for (int i = 1; i <= n; ++i)
if (i == 1 || segment[i].l > last)
++cnt, last = segment[i].r;
printf("%d\n", cnt);
}
return 0;
}