Appoint description:
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
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
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
之前在NYoj(NY题)上也做过这题,不过那里的数据比较水,而poj的数据比较好。
思路:
将各个点全部转化为x轴上的区间,之后找有多少个区间是有交集的,有交集的就跳过,因为只要在交集内可以找到一个点来做雷达的地址。
AC代码:
#include<iostream> #include<algorithm> #include<cstring> #include<string> #include<cstdio> #include<vector> #include<cmath> using namespace std; #define T 1005 int n,m; struct node { double x,y; bool operator<(const node& b) { return x<b.x; } }a[T]; int main() { /*freopen("input.txt","r",stdin);*/ int i,k,c=0,flag; double j,x,y; while(~scanf("%d%d",&n,&m)&&(n||m)) { flag=0; for(i=0;i<n;++i){ scanf("%lf%lf",&x,&y); if(y<0){ n--,i--;continue; } if(y>m)flag=1; j = sqrt((double)(m*m-y*y)); a[i].x = x-j; a[i].y = x+j; } if(flag||m<=0){ printf("Case %d: -1\n",++c); continue; } sort(a,a+n);j=a[0].y; for(i=1,k=1;i<n;++i){ if(a[i].x<=j){ j=min(j,a[i].y); continue; } else { k++; j=a[i].y; } } printf("Case %d: %d\n",++c,k); } return 0; }
这题隔了几个月又重新写了一遍,这次完全没参考到别人的代码,感觉对于贪心的理解又有一大进步了。这次的比上面的代码好理解。
又一次AC代码:
#include<iostream> #include<algorithm> #include<cstring> #include<string> #include<cstdio> #include<cmath> #include<ctime> #include<cstdlib> #include<queue> #include<vector> #include<set> using namespace std; const int T=35000; #define inf 0x3f3f3f3fL typedef long long ll; struct node { double L,R; }a[T]; int n,m; bool cmp(const node& a,const node& b){ return a.L<b.L||(a.L==b.L&&a.R>b.R); } double fun(int x,int y) { return sqrt(m*m*1.0-y*y*1.0); } int main() { #ifdef zsc freopen("input.txt","r",stdin); #endif int i,j,k,cnt=0; while(~scanf("%d%d",&n,&m)&&(n||m)) { bool flag = false; for(i=0;i<n;++i){ scanf("%d%d",&j,&k); if(k>m)flag = true; a[i].L = j-fun(j,k); a[i].R = j+fun(j,k); } if(flag){ printf("Case %d: %d\n",++cnt,-1); continue; } sort(a,a+n,cmp); double L,R; for(i=0,k=0;i<n;++i){ k++; if(i<n){ L = a[i].L,R = a[i].R; i++; } while(L<=R&&R>=a[i].L&&i<n){ L = max(L,a[i].L); R = min(R,a[i].R); ++i; } i--; } printf("Case %d: %d\n",++cnt,k); } return 0; }