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
Sample Output
Source
Beijing 2002
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
The input is terminated by a line containing pair of zeros
3 2 1 2 -3 1 2 1 1 2 0 2 0 0
Case 1: 2 Case 2: 1
/*这道题是在寒假的一次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;
}