U - Radar Installation

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. 
 
Figure A Sample Input of Radar Installations


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

题目解析:

输入的是点n个的数目,和雷达m的范围,后面再加上n行点的位置,要求雷达在x轴(x轴指的是海平面,以下同理)上面。题目求的是,要想将所有的点覆盖的雷达数目,求最小的雷达数目。

主要的思路就是将这个题目转换一下去求。题目上面说,雷达只会在x轴上面,那么我们就可以去算一下大致的几种情况:

第一种,雷达全面覆盖的到。那么转换一下思路。

第二种,存在几个特殊的,比较高的位置,雷达无法覆盖,就是雷达最高为m,但是他的位置高度超过了m,所以直接输出-1.

思路就是我们可以把每一个点转换一下,看成一个圆,去思考一下。如果点可以被覆盖的到,那么圆与x轴就会相交或者相切,以半径为雷达m范围的圆。如果他们不相交,那么就是说雷达扫描不到,因为雷达只在x轴上面。

如图:

在这里我们看见了因为相交的部分不重合,所以要想在x轴上面安雷达覆盖这两个点,我们至少需要两个。

如图的思想,我们再加一个点所构成的圆。在此注明一点就是,在x轴上面的范围就是表明雷达如果要覆盖这点,那么他就必须在这个范围里面。因为二点,一必须在x轴上面,二他是以雷达范围的圆,不在就说明点与雷达的范围超过了雷达扫描的范围。

在此图,我们可以更好的看出如果,范围重合了,就说明他们可以用一个雷达去扫描得到。

最后得到的其实就是这个图了,求的就是公共覆盖的就用一点,不是公共覆盖的就开辟,把一个范围不断的缩小,缩小的区域就是共同的雷达,不在缩小的区域类,就代表着,存在一点和你不含有公共区域。

所以题目的思路就清晰了,先把点转化为在x轴上面的范围,求范围的话,根据数学的公式就可以求出来了。[x-根号下(r*r-y*y),x+根号下(r*r-y*y)],这个范围就可以了。最后题目就转换成了求公共覆盖范围用一个雷达,不在就新建一个雷达。

代码如下:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>

using namespace std;

struct node
{
    double left;
    double right;
} a[1003];


bool cmp(node n,node m)
{
    return n.left<m.left;
}

int main()
{
    int n;
	double m;
    int count=1;
    while(scanf("%d%lf",&n,&m)!=EOF)
    {
        if(n==0 && m==0) break;
        double k,t;
        bool flag = false;
        for(int i=0; i<n; i++)
        {
            scanf("%lf%lf",&k,&t);
            a[i].left = k - sqrt((double)m*m-(double)t*t);
            a[i].right = k + sqrt((double)m*m-(double)t*t);
            if(t>m || m<0)
                flag=true;
        }
        //超出范围,无法扫描到。
        if(flag)
        {
            printf("Case %d: %d\n",count++,-1);
        }
        else
        {
            sort(a,a+n,cmp);
			double t=a[0].right;
            int c=1;
            for(int i=1; i<n; i++)
            {
                if(a[i].right<=t)
                    t = a[i].right;
                else
                {
                    if(a[i].left>t)
                    {
                        t=a[i].right;
                        c++;
                    }
                }
            }
            printf("Case %d: %d\n",count++,c);
        }
    }
    return 0;
}
posted @ 2017-07-21 20:43  让你一生残梦  阅读(181)  评论(0编辑  收藏  举报