Radar Installation
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.
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
Source
题意:就是雷达放x轴上,探测范围为d为半径的圆,小岛在第一第二象限,要你用最少的雷达数覆盖所有小岛。如果其中有一个岛找不到就输出-1。
分析:1.先要把问题进行转化一下,转化为如果想要探测到小岛,雷达应该放在x轴的哪一个范围内,方法就是以岛为圆心,作半径为d的圆,该圆与x轴的交点间的范围就是要探测该岛雷达可以放置的位置。把这些范围用一条一条的线段表示。
2.把这些线段的左端点按从小到大的顺序排列,为了尽可能使雷达数少,我们可以遍历一条一条的线段,然后记下当前线段的最小右端点,如果接下来出现的线段的左端点比该最小右端点大,则加一个雷达。
3.还需要注意点的坐标可以为小数。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <algorithm>
using namespace std;
struct Node{
double left,right;
}f[2100];//f表示每一个小岛的可放置雷达的范围,
int cmp(Node a,Node b)
{
return a.left<b.left;
}//这些范围按左边起点从小到达排序
int x[2100],y[2100];//为岛的坐标,可以为小数,所以后面要做一下转换处理
int main()
{
int i,j;
int n,d;
int s=0,flag,num;//s为输入的组数,flag用于判断是否存在到不了的小岛
double k,p;//k表示小岛的横坐标到左右两边的距离
while(scanf("%d %d",&n,&d)!=EOF){
if(n==0&&d==0){
break;
}
s++;
flag=0;
for(i=0;i<n;i++){
scanf("%d %d",&x[i],&y[i]);
if(y[i]>d){
flag=-1;
}
}
if(flag==-1){
printf("Case %d: -1\n",s);
}
else{
for(i=0;i<n;i++){
k=sqrt(d*d*1.0-y[i]*y[i]*1.0);
f[i].left=(double)x[i]-k;
f[i].right=(double)x[i]+k;
}
sort(f,f+n,cmp);
num=0;
p=-1e9;
for(i=0;i<n;i++){//核心:记下当前所以范围中的最小的right,如果下一个范围的left大于这个最小的right,那雷达数加1
if(f[i].left>p){
num++;
p=f[i].right;
}
else if(f[i].right<p){
p=f[i].right;
}
}
printf("Case %d: %d\n",s,num);
}
}
return 0;
}