一.题目链接:

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;
}