Radar Installation

Description Assume the coasting is an infinite straight line. Land is in one side of coasting, sea in the other. Each small island is a point locating in the sea side. And any radar installation, locating on the coasting, can only cover d distance, so an island in the sea can be covered by a radius installation, if the distance between them is at most d.

We use Cartesian coordinate system, defining the coasting is the x-axis. The sea side is above x-axis, and the land side below. Given the position of each island in the sea, and given the distance of the coverage of the radar installation, your task is to write a program to find the minimal number of radar installations to cover all the islands. Note that the position of an island is represented by its x-y coordinates.

Figure A Sample Input of Radar Installations
Input The input consists of several test cases. The first line of each case contains two integers n (1<=n<=1000) and d, where n is the number of islands in the sea and d is the distance of coverage of the radar installation. This is followed by n lines each containing two integers representing the coordinate of the position of each island. Then a blank line follows to separate the cases.

The input is terminated by a line containing pair of zeros Output For each test case output one line consisting of the test case number followed by the minimal number of radar installations needed. "-1" installation means no solution for that case. Sample Input
3 2
1 2
-3 1
2 1

1 2
0 2

0 0
Sample Output
Case 1: 2
Case 2: 1
Source Beijing 2002
/*这道题是在寒假的一次2tan xincontest上看到的, 想了想没有思路, 不知道如何下手, 后看题解时也内心烦躁, 根本看不下去, 后来实在mooc上郭炜老师讲贪心专题时, 才听了进去, 虽然和郭炜老师的贪心思路不一样, 但是我的贪心思路也AC了, 虽然没有严格证明自己的思路是否完全正确, 但是直觉上和AC可以说这种思路并没有错误. 还可以明确贪心并不是只有一种思路. 这道题的二维转一维也是奇妙的地方. */#include<iostream>
#include<algorithm>
#include<queue>
#include<cmath>
using namespace std;
const int maxn = 1050;
const int inf = 0x3f3f3f3f;//无穷大, 此为无穷大的好处是inf + inf不会超过int
struct island{
    int x, y;
    double left, right;
    bool operator < (const island & rhs) const
    {
        return right > rhs.right;//重载运算符, 因为要从右端点最小的开始, 所以这里是大于号
    }
};
island ils[maxn];
int main()
{
    ios::sync_with_stdio(false);
    int n, d;
    int kase = 0;
    while(cin >> n >> d){
        if(n == 0 && d == 0)
            break;
        int cnt = 0;
        double position = -inf;
        bool flag = false;
        cout << "Case " << ++kase << ": ";
        priority_queue<island> pq;
        for(int i = 0; i < n; ++i){
            int & x = ils[i].x;//引用, 简单点
            int & y = ils[i].y;
            cin >> x >> y;
            if(y > d)//这里设置一个flag, 出现无解不能立即停止读取数据, 要继续读取
                flag = true;//此样例剩余的数据
            double limit = sqrt(pow(d, 2) - pow(y, 2));//勾股定理确定端点
            ils[i].left = x - limit;//low
            ils[i].right = x + limit;//high
            pq.push(ils[i]);
        }
        if(flag)
            cout << "-1" << endl;
        else{
            while(!pq.empty()){//贪心思路: 如果要最少数量的雷达, 第一个点可以是最先结束的右端点
                const island & obj = pq.top();//如果上一个雷达安置点, 照不到当前节点, 就在当前节点的右端点放置一个雷达(递归了)
                //pq.pop()// pop()在这里是不行的
                if(position < obj.left){
                    ++cnt;
                    position = obj.right;
                }
                pq.pop();
            }
            cout << cnt << endl;
        }
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/u013482363/article/details/79154580