每次打代码打得特别惨我就想找个人类聊聊天。
题意:
x轴上方为海,其中某些整点位置存在一共n个岛屿,在x轴(海岸)上安排一些灯塔,每个灯塔的扫描半径都为d,求最少需要多少个灯塔。
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.
一开始贪错了,按先x正向后y反向的顺序排,再找,结果WA了几遍,上厕所的时候想明白了反例。
用勾股定理可以求得每个岛在x轴上有一段范围灯塔在其中就可以扫到,因此岛的坐标其实就是这么一个区间,然后就变成了最少点覆盖区间的经典贪心问题了。
代码如下:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<algorithm>
using namespace std;
#define mxn 1010
bool dcmp(double a,double b){
return fabs(a-b)<0.0001;
}
double d;
struct point{
double x,y;
bool operator < (const point& in)const{
return x+sqrt(d*d-y*y)<in.x+sqrt(d*d-in.y*in.y);
}
point(){}
point(double _x,double _y){x=_x,y=_y;}
}p[mxn];
bool flag[mxn];
int n;
int main(){
int cs=0;
while(scanf("%d%lf",&n,&d)!=EOF){
if(!n&&dcmp(d,0)) break;
memset(flag,0,sizeof(flag));
int ans=0;
for(int i=0;i<n;++i){
scanf("%lf%lf",&p[i].x,&p[i].y);
if(p[i].y>d) ans=-1;
}
if(ans==-1){
printf("Case %d: -1\n",++cs);
continue;
}
sort(p,p+n);
for(int i=0;i<n;++i){
if(flag[i]) continue;
flag[i] = true;
double now=p[i].x+sqrt(d*d-p[i].y*p[i].y);
for(int j=i+1;j<n;++j){
double cur=p[j].x-sqrt(d*d-p[j].y*p[j].y);
if(cur<now||dcmp(cur,now)){
flag[j]=true;
continue;
}
break;
}
++ans;
}
printf("Case %d: %d\n",++cs,ans);
}
return 0;
}