问题描述
假设海岸线是一条无限的直线。海岸的一边是陆地,另一边是海洋。每一个小岛都是位于海边的一个点。而任何位于海岸上的雷达装置只能覆盖d距离,如果它们之间的距离最多为d,半径可以覆盖海洋中的岛屿。
我们使用笛卡尔坐标系,定义海岸线是x轴。海的一面在x轴之上,陆地的一面在x轴之下。给定海洋中每个岛屿的位置,以及雷达装置覆盖的距离d,您的任务是编写一个程序来找到覆盖所有岛屿的雷达装置的最小数量。注意,岛屿的位置是由它的x-y坐标表示的。
输入
输入
输入由几个测试用例组成。每种情况的第一行都包含两个整数n (1<=n<=1000)和d,其中n为海洋中岛屿的数量,d为雷达安装覆盖的距离。后面有n行,每一行包含两个整数,表示每个岛屿的位置坐标。然后后面跟着一个空行来分隔大小写。
输入以包含一对零的行结束
输出
对于每个测试用例输出,一行由测试用例编号和所需雷达安装的最小数量组成。“-1”安装意味着这种情况没有解决方案。
示例

思路
本题适用贪心算法,本人对于定义之类的东西并不敏感,在此只把个人的思路解释一下,不对贪心算法进行任何解释。
拿半径为5的雷达,坐标为(1,3)(5,4)的两个岛屿举例,若要检测到(1,3)岛屿,因为雷达半径为5,所以,雷达可以安设在海岸线上[(-3,0),(7,0)]范围内,(5,4)岛屿的范围也是这样计算,这样的话,我们就得到了两条雷达布设范围线段,这两条线段的重合之处就能同时顾及两座小岛。岛屿多起来的话道理也都是一样的。
因为岛屿的输入是随机的,没有任何顺序,我们需要根据某项指标进行排序,因为我们观察坐标轴一般更习惯从左往右观察,对最左侧(根据某项指标进行的排序)的岛屿的观察不应该浪费太多的雷达布设范围,所以我们应该在最左侧的岛屿的雷达布设范围的最右侧,也就是线段的最右端安装一台雷达,这样既可以监测到最左侧岛屿,又不会浪费这台雷达的布设范围(刚好能够监测到最左侧岛屿),综合起来考虑,我们决定以雷达布设范围线段的右端进行从小到大排序。这样我们就得到了一些存储有序的线段,考虑下面的情况,我们已经对最左侧的岛屿进行了监测,雷达布置在最左侧岛屿的雷达布设线段的最右端,如果下一座岛屿的雷达布设线段的最左端小于等于上一座岛屿的雷达布设线段的最右端,那么他们就出现了重合,这时不必再添加新的雷达,即可以把这座岛屿忽略,然后取下一座小岛,做为第二座小岛(第一座小岛不变,还是原来的那个),如此重复,直到遇到下一座岛屿的雷达布设线段的最左端大于上一座岛屿的雷达布设线段的最右端,这种情况就说明,一台雷达无法兼顾这二者,我们需要新安装一台雷达,因为我们是按照雷达布设线段的最右端进行排序,所以新的岛屿(不能忽略的)一旦出现,就意味着我们带着先前已经布置的雷达数量,又开始了新一轮的统计。就这样,每统计一轮,就会多一台雷达,最终得到最小的雷达数目。
代码如下
#include<iostream>
#include<algorithm>
#include<math.h>
using namespace std;