这是一道贪心的题目,首先我们要知道,我们放置雷达的话我们可以做一个转换,就是已知岛屿的点坐标的时候,我们可以算一下,这个点以d为半径与x轴交点之间的线段在x轴上的投影,然后我们只需要在这个投影范围内设置一个雷达就可以了。

然后我们读入数据的时候,因为题目中说道,如果计算不出结果我们就输出-1,一般来是可以得到结果的,所以如果出现异常,那肯定是数据的锅。

我们读的时候判断一下y值,如果大于d的值的话,我们就给一个flag标记,然后在读入完成之后,直接输出-1,跳出这重循环,继续对下一组数据进行操作。

根据之前的投影,我们只需要记录每个岛屿的投影开始的x值和结束的x值就可以了。

接下来我们就开始计算这雷达的安放数目了,我们可以知道如果在同一个雷达的作用范围可以覆盖多个岛屿的话,我们就在这些处于同一范围的岛屿的最后一个岛的投影开始x值处,安放一个雷达就可以了。

这是因为如果这些岛屿若不能被这个雷达覆盖的话,就是两种情况:

第一种情况就是,其中的一个岛屿的它的左端点已经超过了最右边的那个端点的开始x值,这样就与我们的假设矛盾了,所以不成立。

第二种情况就是,其中的一个岛屿的右端点小于了最右边的那个岛屿的左值,这样子的话,它又与我们的假设相矛盾了。因为如果小于左值,就说明它的范围已经不跟后面的岛是同一个范围的了,一个雷达是不可能覆盖这些岛屿的。

我们执行的时候,也是进行两重循环,第一重循环推进岛屿,第二重循环就从上次未覆盖的岛屿开始直到一重循环的i值-1的位置,进行比对,比较这之间的岛屿的结束位置是否大于岛屿i的开始位置,如果大于,就不做任何操作。

如果小于就说明除了岛屿i之外,上次未覆盖岛屿到i-1的岛屿是处在同一个雷达范围之下的,我们在i-1直接设置一个雷达即可。

这样子的话,就是ans++的操作,然后更新最新的未被覆盖的岛屿的位置,然后跳出内层循环。

但是ans这个值的话,我们要给它设置成1,因为如果只有一个岛屿的话,我们进入循环之后就会发现i=0,此时第一次进入,最新未被覆盖的岛屿位置也是0,然后我们无法进入内层循环,然后就无法进行++操作。

但是我们设置为1的目的并不是为了第一个岛,这也与我们的初衷相悖,与我们的思路不一样,我们设置的目的是为了给最后一个岛进行加一的操作。

我们可以分析一下, 最后一个岛的情况,第一,它被之前的岛覆盖了,外层循环走到最后一个岛,内层循环进行比较,然后发现没有结束的岛屿位置,也就是下一次的岛屿不能全部覆盖的那个岛屿位置。

我们失去了结束的位置,然后ans就不能++,所以我们直接加1。另一种情况就是最后一个岛屿也不被覆盖,但是内层循环依旧找不到结束的位置,这样内层循环结束,外层循环结束,ans依旧没有加加。

所以我们直接给它设置成1,至于贪心算法的正确性其实还有几句话,但是看不看都已经无所谓了,直接看代码去吧。

正确性:

假设你觉得有一个雷达的放置序列是最少的,最佳的,然后我们按照上面的方法得出的是另一个最佳结果。

好,我们来比较这两个序列,设它们的开始是x1和y1(都是x的坐标)。

如果x1<y1,此时,x1所覆盖的岛屿必能被y1所覆盖,这时候我们就可以用y1替换x1。

如果x1>y1,这时候又分为两种情况,第一就是y1<x1<y2,因为x1不能覆盖y2范围内的岛屿,所以我们这时候放置的y1不会有损失,我们可以覆盖所有的岛屿。

如果它大于x2,这时候,根据我们的贪心策略,如果我们在i放置雷达,是因为我们如果在i+1的位置放置雷达,那就无法覆盖i位置上的雷达了。

所以如果x1>y2的话,它本身也无法覆盖1位置上的雷达,所以它本身就不是一个正确的策略了。

所以贪心解法就是正确的。

  1. #include <cstdio>
  2. #include <cmath>
  3. #include <algorithm>
  4. using namespace std;
  5. const double eps=1e-6;
  6. struct Island {
  7. double Sx,Ex;
  8. bool operator < (const Island &b)const {
  9. return Ex<b.Ex;
  10. }
  11. }island[1010];
  12. int main()
  13. {
  14. int n,d,x,y,cnt=1;
  15. while (~scanf("%d%d",&n,&d)&&n&&d) {
  16. int error=0;
  17. for (int i=0;i<n;i++) {
  18. scanf("%d%d",&x,&y);
  19. if (y>d)
  20. error=1;
  21. island[i].Sx=x-sqrt(d*d-y*y);
  22. island[i].Ex=x+sqrt(d*d-y*y);
  23. }
  24. if (error) {
  25. printf("Case %d: %d\n",cnt++,-1);
  26. continue;
  27. }
  28. sort(island,island+n);
  29. int end=0;
  30. int ans=1;
  31. for (int i=0;i<n;i++) {
  32. for (int j=end;j<i;j++) {
  33. if (island[i].Sx-island[j].Ex<eps) {
  34. continue;
  35. }
  36. else {
  37. ans++;
  38. end=i;
  39. break;
  40. //此时i-1已经被覆盖
  41. }
  42. }
  43. }
  44. printf("Case %d: %d\n",cnt++,ans);
  45. }
  46. return 0;
  47. }

POJ-1328-放置雷达的更多相关文章

  1. poj 1328 安雷达问题 贪心算法

    题意:雷达如何放置?在xoy二维平面坐标系里面,x轴上方的为岛屿,x轴下方的是雷达要放到位置,如何放使得雷达放的最少? 思路 肯定放在x轴上减少浪费是最好的选择 什么情况下,雷达无法到达呢?--以这个 ...

  2. POJ 1328 安装雷达 (贪心)

    <题目链接> 题目大意: 以x轴为分界,y>0部分为海,y<0部分为陆地,给出一些岛屿坐标(在海中),再给出雷达可达到范围,雷达只可以安在陆地上,问最少多少雷达可以覆盖所以岛屿 ...

  3. poj 1328

    http://poj.org/problem?id=1328 题意:题目大概意思就是有一群孤岛,想要用雷达来监视这些岛屿,但雷达的范围是有限的,所以需要多个雷达,题目就是要你解决最少需要几个雷达,注意 ...

  4. poj 1328 Radar Installation(贪心)

    题目:http://poj.org/problem?id=1328   题意:建立一个平面坐标,x轴上方是海洋,x轴下方是陆地.在海上有n个小岛,每个小岛看做一个点.然后在x轴上有雷达,雷达能覆盖的范 ...

  5. poj 1328 Radar Installatio【贪心】

    题目地址:http://poj.org/problem?id=1328 Sample Input 3 2 1 2 -3 1 2 1 1 2 0 2 0 0 Sample Output Case 1: ...

  6. 贪心 POJ 1328 Radar Installation

    题目地址:http://poj.org/problem?id=1328 /* 贪心 (转载)题意:有一条海岸线,在海岸线上方是大海,海中有一些岛屿, 这些岛的位置已知,海岸线上有雷达,雷达的覆盖半径知 ...

  7. POJ 1328 Radar Installation【贪心】

    POJ 1328 题意: 将一条海岸线看成X轴,X轴上面是大海,海上有若干岛屿,给出雷达的覆盖半径和岛屿的位置,要求在海岸线上建雷达,在雷达能够覆盖全部岛屿情况下,求雷达的最少使用量. 分析: 贪心法 ...

  8. POJ 1328 Radar Installation 贪心 A

    POJ 1328 Radar Installation https://vjudge.net/problem/POJ-1328 题目: Assume the coasting is an infini ...

  9. 雷达装置 (POJ 1328/ codevs 2625)题解

    [问题描述] 假定海岸线是一条无限延伸的直线,陆地在海岸线的一边,大海在另一侧.海中有许多岛屿,每一个小岛我们可以认为是一个点.现在要在海岸线上安装雷达,雷达的覆盖范围是d,也就是说大海中一个小岛能被 ...

  10. poj 1328 Radar Installation

    题目链接:http://poj.org/problem?id=1328 题意:给出海上有n个小岛的坐标,求发出的信号可以覆盖全部小岛的最少的雷达个数.雷达发射信号是以雷达为圆心,d为半径的圆,雷达都在 ...

随机推荐

  1. combobox级联检索下拉选择框

    1.效果图 2.前端 @{ ViewBag.Title = "Index"; Layout = null; @*自动筛选下拉框*@ <script src="~/S ...

  2. oatu2.0认证原理(转)

    今天有时间总结一下: 一.OAuth是一个关于授权(authorization)的开放网络标准,在全世界得到广泛应用,目前的版本是2.0版. 在详细讲解OAuth 2.0之前,需要了解几个专用名词,理 ...

  3. POJ 1151 Atlantis(扫描线)

    题目原链接:http://poj.org/problem?id=1151 题目中文翻译: POJ 1151 Atlantis Time Limit: 1000MS   Memory Limit: 10 ...

  4. Python文件将日志文件中每天的日志拿出来

    file_log.txt文件内容如下: with open('file_log.txt', 'r', encoding='utf-8') as f: for i in f: s = i.split() ...

  5. 构造 Bubble Cup 8 - Finals D. Tablecity

    题目传送门 题意:在1000*2的格子里,在每个小时能派出两个警察在两个地点搜查小偷,求在2015小时内能抓住小偷的方案. 分析:首先每次扫过一列即i1 i2从左往右扫,这样会漏掉小偷正好从间隙穿过的 ...

  6. 牛客练习赛25-A-因数个数和

    题目描述 q次询问,每次给一个x,问1到x的因数个数的和. 输入描述: 第一行一个正整数q:接下来q行,每行一个正整数x 输出描述: 共q行,每行一个正整数表示答案 输入 4 1 2 3 10 输出 ...

  7. 维骨力Glucosamine的最关键的几点...

    1.每日劑量應為多少?長期服用安全嗎? 由於葡萄糖胺(Glucosamine)和軟骨素(Chondroitin)原來就存在於人體,是人體每天會生產製造的必需營養素,因此,一般認為服用此類產品的安全性相 ...

  8. MySQL FailOver(官方自带,free)

    为什么 传统复制和GTIDs切换的缺点 当replication故障出现之后,最头疼是replication架构的调整 一旦master down了,就需要配置某一台slave作为master sla ...

  9. 3个解析url的php函数

    通过url进行传值,是php中一个传值的重要手段.所以我们要经常对url里面所带的参数进行解析,如果我们知道了url传递参数名称,例如 /index.php?name=tank&sex=1#t ...

  10. 【经验总结】VS2010下建立MFC程序

    孙鑫的MFC教学视频非常不错,但是由于视频中孙鑫老师采用VC6.0版本,而现在 许多人都转向了使用VS,VS为我们生成了许多不需要的代码,这也导致在这节课的学习编程中总是遇到一些困难.那么,如何去掉这 ...