装雷达

  题目大意,就是令在海岸线的(直线)一边是海(y>0),另一边是陆地(y<=0),在海岸线上装雷达,雷达可以覆盖的范围为d,海上有岛,(x,y),问你应该怎么装雷达,才能做到技能雷达的检测范围覆盖全部的岛,又能使雷达安装最少?(不能做到输出-1)

  我的思路,首先是把岛排一次序,然后从x坐标最小的那个岛开始贪心算法,怎么做呢?那就是用x=sqrt(d*d-y*y)+xa,来获得当前岛的安装最远的雷达的位置,然后不断往前找,在超越当前雷达圆心距离之前,不断缩小雷达的位置,使雷达能覆盖到更多的岛,直到岛的横坐标超出雷达中心。

  接下来把当前的雷达中心为圆心,把覆盖在圆内的岛全部找出来,这能使一个雷达能覆盖岛最多,然后从最靠近雷达的第一个没被覆盖的岛开始,重复上述过程。

  

 #include <iostream>
#include <functional>
#include <algorithm>
#include <math.h> using namespace std;
typedef double Position;
typedef struct coordinate
{
Position x;
Position y;
}Pos;
int fcmop(const void* a, const void *b)
{
return (*(Pos *)a).x > (*(Pos *)b).x ? : -;
} static Pos islands[];
static bool used[];
int Search(const int, const int);
bool Judge(const int,const int);
double dist(Pos, Position);
Position get_radar_pos(Pos, const int); int main(void)
{
int Sum_Of_Islands, Distance_Of_Radar, k = , ans;
while (~scanf("%d%d", &Sum_Of_Islands, &Distance_Of_Radar))
{
if (Sum_Of_Islands == && Distance_Of_Radar == )
break;
for (int i = ; i < Sum_Of_Islands; i++)
scanf("%lf%lf", &islands[i].x, &islands[i].y);
qsort(islands, Sum_Of_Islands, sizeof(Pos), fcmop);//把岛都按照顺序排序
memset(used, , sizeof(used));
ans = Search(Sum_Of_Islands, Distance_Of_Radar); printf("Case %d: %d\n", k++, ans);
} return ;
} double dist(Pos a, Position mid)//计算两点之间的距离
{
return sqrt((a.x - mid)*(a.x - mid) + a.y*a.y);
} Position get_radar_pos(Pos a, const int dist)
{
Position k = sqrt((double)(dist*dist) - a.y*a.y) + a.x;
return k;
} bool Judge(const int j, const int Distance_Of_Radar)
{
if (islands[j].y - Distance_Of_Radar > )//不可能找到一个雷达覆盖这个岛,直接退出
return ;
else if (islands[j].y < )
return ;
else return ;
} int Search(const int Sum_Of_Islands, const int Distance_Of_Radar)
{
Position tmp_pos, now_min_pos;
int ans = , tmp_mid, j, now_is = ; if (Distance_Of_Radar <= )//Distance小于0,直接再见
return -;
for (; now_is < Sum_Of_Islands;)
{
if (Judge(now_is, Distance_Of_Radar)) return -;
tmp_mid = now_is;
now_min_pos = get_radar_pos(islands[now_is], Distance_Of_Radar);//初始化最远位置
used[now_is] = ;
for (j = now_is + ; j < Sum_Of_Islands && islands[j].x <= now_min_pos; j++)
{
if (used[j]) continue;//必须没被标记过
if (Judge(j, Distance_Of_Radar)) return -;
used[j] = ;//记得标记
tmp_pos = get_radar_pos(islands[j], Distance_Of_Radar);
if (tmp_pos <= now_min_pos)//必须是不能被覆盖才更新
{
now_min_pos = tmp_pos;
tmp_mid = j;//更新是哪一个岛才是中间岛
}
}
ans++;//建立雷达点
for (j = tmp_mid; j < Sum_Of_Islands && islands[j].x <= now_min_pos + Distance_Of_Radar; j++)//把圈内的岛都排除
{
if (Judge(j, Distance_Of_Radar)) return -;
else if (dist(islands[j], now_min_pos) <= Distance_Of_Radar)
used[j] = ;
}
for (j = tmp_mid; j < Sum_Of_Islands && used[j]; j++);//在中心往前找找到第一个没有被标记的点
now_is = j;
}
return ans;
}

  代码的变量命名已经能很清楚说明我在干什么了

  另外其实代码还可以简化一下,那就是去除used域,其实我们在上面找在雷达圆心右方到那些没被覆盖的岛的时候,我们忽略了其实新的圆也可以与当前作用域重复的,那么我们可以就把used区域去掉,然后把代码改成只要找到在半径外,我们就退出循环。(我就不改了)

  另外这一道题其实是挺著名的区间贪婪算法,只是我没有用区间去做而已

  要做也很简答,思路就是以岛为圆心,雷达监控范围为半径,画圆,与x轴会有两个交点,然后不断去掉重复区间就可以了,如果有区间是重复的,我们就不断缩小区间,如果区间没有交集了,我们就添加一个雷达,重复步骤

  详情见:http://www.cnblogs.com/yu-chao/archive/2011/07/18/2109756.html

  另种方法速度差不多,都是O(n)

  最近真的是忙死我了,都没什么时间做题,哎

Greedy:Radar Installation(POJ 1328)的更多相关文章

  1. Radar Installation POJ - 1328

    Assume the coasting is an infinite straight line. Land is in one side of coasting, sea in the other. ...

  2. Radar Installation POJ - 1328(贪心)

    Assume the coasting is an infinite straight line. Land is in one side of coasting, sea in the other. ...

  3. Radar Installation POJ - 1328 (贪心)

    题目大意(vj上的翻译版本) 假定海岸线是无限长的直线.陆地位于海岸线的一侧,海洋位于另一侧.每个小岛是位于海洋中的一个点.对于任何一个雷达的安装 (均位于海岸线上),只能覆盖 d 距离,因此海洋中的 ...

  4. 贪心 POJ 1328 Radar Installation

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

  5. Poj 1328 / OpenJudge 1328 Radar Installation

    1.Link: http://poj.org/problem?id=1328 http://bailian.openjudge.cn/practice/1328/ 2.Content: Radar I ...

  6. poj 1328 Radar Installation (简单的贪心)

    Radar Installation Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 42925   Accepted: 94 ...

  7. POJ 1328 Radar Installation 贪心 A

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

  8. poj 1328 Radar Installation(nyoj 287 Radar):贪心

    点击打开链接 Radar Installation Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 43490   Accep ...

  9. poj 1328 Radar Installation【贪心区间选点】

    Radar Installation Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 20000/10000K (Java/Other) ...

随机推荐

  1. JEECMS页面中常用标签

    (1)在段落前给每一行加序号 从0开始:${a_index}从1开始:${a_index+1} (2)标记说明 [文章导航]:[@cms.Position /] [文章标题]:${arti.title ...

  2. 洛谷P2015 二叉苹果树

    题目描述 有一棵苹果树,如果树枝有分叉,一定是分2叉(就是说没有只有1个儿子的结点) 这棵树共有N个结点(叶子点或者树枝分叉点),编号为1-N,树根编号一定是1. 我们用一根树枝两端连接的结点的编号来 ...

  3. Android——Canvas类的学习

    转:http://blog.sina.com.cn/s/blog_61ef49250100qw9x.html 今晚瞎折腾,闲着没事画了个机器人——android,浪费了一个晚上的时间.画这丫还真不容易 ...

  4. 关于API的设计与实现

    http://blog.csdn.net/horkychen/article/details/46612899 API的设计是软件开发中一个独特的领域.最主要的特殊点在于API是供开发者使用的界面,即 ...

  5. WebSocket 是什么原理?为什么可以实现持久连接?

    https://www.zhihu.com/question/20215561   作者:Ovear链接:https://www.zhihu.com/question/20215561/answer/ ...

  6. c#接口和抽象类对比学习

    什么是接口? 接口就是一种规范,协议(*),约定好遵守某种规范就可以写通用的代码. 定义了一组具有各种功能的方法.接口描述的是一种能力,具有这种能力的事物可以没任何关系.比如: public inte ...

  7. C++中虚函数的作用浅析

    虚函数联系到多态,多态联系到继承.所以本文中都是在继承层次上做文章.没了继承,什么都没得谈. 下面是对C++的虚函数这玩意儿的理解. 一, 什么是虚函数(如果不知道虚函数为何物,但有急切的想知道,那你 ...

  8. PHP函数之日期时间函数date()使用详解

    date()函数是我们在php开发中常碰到并且会使用到的一个日期函数,下面我来给大家介绍date()函数的一些基本扮靓和方法,有需要了解的朋友可进入参考   日期时间函数是PHP 的核心组成部分.无需 ...

  9. MFC 中控件的启用与禁用

    启用和禁用控件可以调用CWnd::EnableWindow 函数. BOOL EnableWindow(BOOL bEnable = TRUE); 判断控件是否可用可以调用 CWnd::IsWindo ...

  10. JVM<一>----------运行时数据区域

    参考:1.JVM Specification: http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-2.html#jvms-2.5 2.< ...