题意: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
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
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.
Sample Input
3 2 1 2 -3 1 2 1 1 2 0 2 0 0Sample 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; }