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
The input is terminated by a line containing pair of zeros
3 2 1 2 -3 1 2 1 1 2 0 2 0 0
Case 1: 2Case 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; }