poj-1328 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     


分析:以每一个海岛为中心,d为半径画圆,与x轴交于left,right两点,也就是说,在区间[left,right]上任选一个点建雷达都可以把该点覆盖。那么问题就转化为有很多区间,选择最少的点,使得所有区间内都有点存在。用贪心来做。

具体:把线段按左端点从小到大排序,如果左端点相等则按右端点从小到大排序。首先,雷达建在第一个区间的最右端,记为temp,如果下一个区间的左端点大于temp,那么就需要新建一个雷达站,同时更新temp的位置到新建的雷达站的右端。如果下一个区间的左端点小于temp,但右端点大于temp,则不用管,继续判断下一个区间;如果下一个区间左右端点都小于temp,这时候为了覆盖尽可能多的区间,应该把temp往左移动到下一个区间的右端点上。

注意:输入要scanf,temp要声明为double,wa了好多发。。。

#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;

struct iland{
	double x, y;
}land[1020];

struct node{
	double left, right;
}p[1020];

int n;
double d;

bool cmp(const node &a, const node &b){
	if(a.left!=b.left) return a.left<b.left;
	if(a.right!=b.right) return a.right<b.right;
}

void count(int i){
	p[i].left = land[i].x - sqrt(d*d - land[i].y*land[i].y);
	p[i].right = land[i].x + sqrt(d*d - land[i].y*land[i].y);
} 


int main(){
	int T = 1;
	while(scanf("%d %lf", &n, &d)==2 && n){
		int isok = 0;
		for(int i = 0; i<n; i++){
			scanf("%lf %lf", &land[i].x, &land[i].y);
			if(land[i].y>d){
				isok = 1;
			}
		}
		if(isok == 1){
			printf("Case %d: -1\n", T++);
			continue;
		}
		int len = 0;
		for(int i = 0; i<n; i++){
			if(land[i].y<0) continue;
			else{
				p[len].left = land[i].x - sqrt(d*d - land[i].y*land[i].y);
				p[len].right = land[i].x + sqrt(d*d - land[i].y*land[i].y);
				len++;
			}
		}
		sort(p, p+len, cmp);
		int num = 1;
		double temp = p[0].right;
		for(int i = 0; i<n - 1; i++){
			if(p[i+1].left>temp){
				num++;
				temp = p[i+1].right;
			}
			else{
				if(p[i+1].right<temp){
					temp = p[i+1].right;
				}
			}
		} 
		printf("Case %d: %d\n", T++, num);
	}
	return 0;
}

                                                                                                      

猜你喜欢

转载自blog.csdn.net/grimcake/article/details/78005904