一.题目链接:
POJ-1328
二.题目大意:
给 n 个点(均在 y 轴上方),每个点都有一个坐标.
现在 x 轴上建立雷达,每个雷达可以扫描半径为 d 的区域.
求最少需要建立的雷达数,使得每个点都被覆盖.
三.分析:
先计算出每个点在 x 轴上对应的范围 [l, r].
对区间按照 l 值排序.
现考虑何时加雷达以及雷达位置如何更新.
对于第 i 个点来说,雷达的位置应放在 s[i].r.
更新的话,由于前面的都覆盖了,只需要在保证在此条件下,多覆盖一个点.
即:pos = min(pos, s[i].r).
四.代码实现:
#include <set>
#include <map>
#include <ctime>
#include <queue>
#include <cmath>
#include <stack>
#include <bitset>
#include <vector>
#include <cstdio>
#include <sstream>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#define eps 1e-8
#define lc k * 2
#define rc k * 2 + 1
#define pi acos(-1.0)
#define ll long long int
using namespace std;
const int M = (int)1e3;
const ll mod = (ll)1e9 + 7;
const int inf = 0x3f3f3f3f;
struct node
{
double l, r;
}s[M + 5];
bool cmp(node a, node b)
{
return a.l < b.l;
}
int cal(int n)
{
int cnt = 0;
double pos = -inf * 1.0;
sort(s, s + n, cmp);
for(int i = 0; i < n; ++i)
{
if(pos < s[i].l)
{
cnt++;
pos = s[i].r;
}
else
{
pos = min(pos, s[i].r);
}
}
return cnt;
}
int main()
{
int n, d;
int ca = 0;
while(~scanf("%d %d", &n, &d) && (n + d))
{
int x, y;
bool flag = 0;
for(int i = 0; i < n; ++i)
{
scanf("%d %d", &x, &y);
if(flag || y > d)
{
flag = 1;
continue;
}
s[i].l = x - sqrt(d * d - y * y);
s[i].r = x + sqrt(d * d - y * y);
}
int cnt;
if(flag)
cnt = -1;
else
cnt = cal(n);
printf("Case %d: %d\n", ++ca, cnt);
}
return 0;
}