U

来源:互联网 发布:config.php 编辑:程序博客网 时间:2024/04/29 22:38
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 21 2-3 12 11 20 20 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;}

原创粉丝点击