B - Radar Installation

B - Radar Installation

题目大意:

描述:

假设海岸线是一条无限长的直线,陆地位于海岸线的一边,大海位于海岸线的另一边。大海中有许多小岛。某安全部门为了监视这些岛上是否有敌人入侵,打算在海岸线上安装若干个雷达来检测岛屿的情况。每个雷达的覆盖范围是以雷达中心为圆心,半径为d的圆形区域。

我们用平面之间坐标系来表示整个区域,海岸线为x轴,大海位于x轴上方,陆地位于x轴下方。为了节约成本,安全部门想使用最少的雷达覆盖所有的岛屿。现在已知每个岛屿的坐标(x,y)和雷达的覆盖半径d,你的任务就是计算出能够覆盖所有岛屿的最少雷达数量。

输入:

输入包含若干组数据。每组数据的第一行有两个整数n(1<=n<=1000)和d,分别表示岛屿的数量和雷达的覆盖半径,之后的n行,每行有两个整数,表示第i个岛屿的坐标(xi,yi),相邻的两组数据使用一个空行隔开。输入“0 0”表示输入结束。

输出:

对于每一组数据的输出格式为“Case i: x”,表示第i组数据中最少需要x个雷达来覆盖所有的岛屿;x=-1表示这组数据无解(无法覆盖所有的岛屿)

解题思路:

其实这是一道区间问题,只要将雷达的位置转为区间来看待就行了。
结合岛屿坐标和雷达覆盖半径,运用勾股定理确定最左和最右的横坐标,以此来确定一个坐标的雷达覆盖区域区间。

 cost = sqrt(R*R-y*y);//确定区间
                c[i].x1 = x - cost; 
                c[i].x2 = x + cost;

然后进行排序,从最左边开始寻找公共区域,存在公共区域即可公用一个雷达。

		sort(c+1,c+1+n,cmp);//对坐标进行排序
        cost = c[1].x2 ;//从最左边的坐标开始寻找
        
        for(i = 2; i <= n; i ++)
        {
            if(c[i].x1 > cost)//没有公共区域
            {
                ans ++;
                cost = c[i].x2 ;
            }
            else if(c[i].x2 < cost)//存在公共区域
                cost = c[i].x2 ;
        }

完整代码如下:

#include<bits/stdc++.h>
using namespace std;
#define N 1100
struct node {
    double x1,x2;//储存最左和最右的横坐标
}c[N];

double cmp(struct node a,struct node b)
{
    if(a.x1 > b.x1 )
        return a.x1 < b.x1 ;
}
int main()
{
    int i,j,n,R,ans,t=0;
    double x,y,cost;
    while(true)
    {
        scanf("%d%d",&n,&R);
        if(n==0 && R==0)break;

        ans = 1;
        if(R <= 0)//半径小于0显然不符合题意 
            ans = -1;

        for(i = 1; i <= n; i ++)
        {
            scanf("%lf%lf",&x,&y);
            if(fabs(y) > R)//纵坐标大于半径显然也不符合提意 
            {
                ans = -1;
            }
            else
            {
                cost = sqrt(R*R-y*y);//确定区间
                c[i].x1 = x - cost; 
                c[i].x2 = x + cost;
            }
        }
        if( ans == -1)
        {
            printf("Case %d: %d\n",++t,ans);
            continue;
        }
        sort(c+1,c+1+n,cmp);//对坐标进行排序
        cost = c[1].x2 ;//从最左边的坐标开始寻找
        
        for(i = 2; i <= n; i ++)
        {
            if(c[i].x1 > cost)//没有公共区域
            {
                ans ++;
                cost = c[i].x2 ;
            }
            else if(c[i].x2 < cost)//存在公共区域
                cost = c[i].x2 ;
        }
        printf("Case %d: %d\n",++t,ans);
    }
    return 0;
}
/*
Sample Input 
3 2 
1 2 
-3 1 
2 1

1 2 
0 2

0 0 
Sample Output 
Case 1: 2 
Case 2: 1
 */
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值