Radar Installation(贪心+区间)

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

Beijing 2002

题意:就是雷达放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;
}

猜你喜欢

转载自blog.csdn.net/weixin_42105789/article/details/84573936