POJ1328 Radar Installation区间贪心

Radar Installation

来源:http://poj.org/problem?id=1328

Time Limit: 1000MS Memory Limit: 10000K

Total Submissions: 112280 Accepted: 24755

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.

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

题意:

就是雷达放x轴上,探测范围为d为半径的圆,小岛在第一第二象限,要你用最少的雷达数覆盖所有小岛。如果其中有一个岛找不到就输出-1。

分析:

1.先要把问题进行转化一下,转化为如果想要探测到小岛,雷达应该放在x轴的哪一个范围内,方法就是以岛为圆心,作半径为d的圆,该圆与x轴的交点间的范围就是要探测该岛雷达可以放置的位置。把这些范围用一条一条的线段表示。

2.把这些线段的左端点按从小到大的顺序排列,为了尽可能使雷达数少,我们可以遍历一条一条的线段,然后记下当前线段的最小右端点,如果接下来出现的线段的左端点比该最小右端点大,则加一个雷达。

3.还需要注意点的坐标可以为小数。

注意:

1、min(current,arr[i].right) 取最小

2、结构体的left right是经过转化后的,是覆盖的坐标范围,不是输入的x y 。经过输入的x,y 再进行转化为left right

代码实现:

//注意更新的时候,current=min(current,arr[i].right)!!!取min
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
const int MAXN=1010;
struct Interval
{
    double left;//坐标可能是小数
    double right;
};
bool compare(Interval x,Interval y)
{
    return x.left<y.left;
}
int main()
{
    Interval arr[MAXN];
    int n,d;
    int casenumber=0;
    while(scanf("%d%d",&n,&d)!=EOF)
    {

        bool flag=true;
        if( n==0 && d==0)
            break;
        for(int i=0;i<n;i++)
        {
            int x,y;
            cin>>x>>y;
            if(y>d)//相离 无论如何安装,固定d后,均不能覆盖到岛屿
                {flag=false;}
            else
                {
                    arr[i].left=x-sqrt(d*d*1.0-y*y);
                    arr[i].right=x+sqrt(d*d*1.0-y*y);
                }
        //输入结束
        //根据分析,按照雷达的左端点按照从小到大排序
        }
        if(flag==false)
            printf("Case %d: %d\n",++casenumber,-1);
        else
        {
             sort(arr,arr+n,compare);//升序
             double current_location=arr[0].right;//因为是按照左端从小到大排列,为了涉及范围更大,把第一个雷达安装在第一个岛屿设计范围的右端点处
             int answer=1;
             for(int i=1;i<n;i++)
             {
                 if(arr[i].left<=current_location)
                 {
                     current_location=min(current_location,arr[i].right);
                     //为什么要取最小的右端点??min!!!!!!!!!!!!
                     //
                 }else
                 {
                     answer++;
                     current_location=arr[i].right;
                 }
             }
             printf("Case %d: %d\n",++casenumber,answer);
        }
    }
    return 0;
}

结果:

注意:

全部评论

相关推荐

门口唉提是地铁杀:之前b站被一个游戏demo深深的吸引了。看up主页发现是个初创公司,而且还在招人,也是一天60。二面的时候要我做一个登录验证和传输文件两个微服务,做完要我推到github仓库,还要我加上jaeger和一堆运维工具做性能测试并且面试的时候投屏演示。我傻乎乎的做完以后人家跟我说一句现在暂时不招人,1分钱没拿到全是白干
你的秋招第一场笔试是哪家
点赞 评论 收藏
分享
06-27 12:54
已编辑
门头沟学院 Java
累了,讲讲我的大学经历吧,目前在家待业。我是一个二本院校软件工程专业。最开始选专业是觉得计算机感兴趣,所以选择了他。本人学习计算机是从大二暑假结束开始的,也就是大三开始。当时每天学习,我个人认为Java以及是我生活的一部分了,就这样持续学习了一年半,来到了大四上学期末,大概是在12月中旬,我终于找的到了一家上海中厂的实习,但我发现实习生的工作很枯燥,公司分配的活也不多,大多时间也是自己在自学。就这样我秋招末才找到实习。时间来到了3月中旬,公司说我可以转正,但是转正工资只有7000,不过很稳定,不加班,双休,因为要回学校参加答辩了,同时当时也是心高气傲,认为可以找到更好的,所以放弃了转正机会,回学校准备论文。准备论文期间就也没有投递简历。然后时间来到了5月中旬,这时春招基本也结束了,然后我开始投递简历,期间只是约到了几家下场面试。工资也只有6-7k,到现在我不知道该怎么办了。已经没有当初学习的心劲了,好累呀,但是又不知道该干什么去。在家就是打游戏,boss简历投一投。每天日重一次。26秋招都说是针对26届的人,25怎么办。我好绝望。要不要参加考公、考研、央国企这些的。有没有大佬可以帮帮我。为什么感觉别人找工作都是顺其自然的事情,我感觉自己每一步都在艰难追赶。八股文背了又忘背了又忘,我每次都花很长时间去理解他,可是现在感觉八股、项目都忘完了。真的已经没有力气再去学习了。图片是我的简历,有没有大哥可以指正一下,或者说我应该走哪条路,有点不想在找工作了。
码客明:太累了就休息一下兄弟,人生不会完蛋的
如果实习可以转正,你会不...
点赞 评论 收藏
分享
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务