题意: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
Output
Sample Input
Sample Output
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
The input is terminated by a line containing pair of zeros
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.
3 2 1 2 -3 1 2 1 1 2 0 2 0 0
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;
}