[POJ1328]Radar Installation【贪心】
Radar Installation
时间限制: 1000MS 内存限制: 10000K
中文题目描述
假定滑行是无限的直线。陆地在海岸的一边,海边在另一边。每个小岛都是位于海边的一个点。而任何位于海岸线上的雷达装置只能覆盖d距离,因此如果它们之间的距离最多为d,则海中的岛屿可以被半径安装覆盖。
我们使用笛卡尔坐标系,定义滑行是x轴。海边在x轴以上,陆地在下面。考虑到每个岛屿在海中的位置,并考虑到雷达安装覆盖的距离,您的任务是编写一个程序,以找到覆盖所有岛屿的最少数量的雷达装置。请注意,岛的位置由其xy坐标表示。
图A雷达安装示例输入
输入格式
输入由几个测试用例组成。每种情况的第一行包含两个整数n(1 <= n <= 1000)和d,其中n是海中岛的数量,d是雷达装置的覆盖距离。接下来是n行,每行包含代表每个岛屿位置坐标的两个整数。然后一个空白行分开的情况。
输入由包含一对零的行终止
输出格式
对于每个测试用例,输出一行包含测试用例编号,然后是最小数量的雷达安装。“-1”安装意味着无法解决这种情况。
示例输入
3 2
1 2
-3 1
2 11 2
0 20 0
示例输出
Case 1: 2
Case 2: 1
资源
北京2002年
题解
我们有个贪心的想法,尽量多的覆盖,但是,不能断空,也就是俩相邻的雷达之间有没被覆盖的岛屿。
我们知道线段上的某一段刚好能覆盖这座岛,然后这道题就退化成了线性的,然后排序+贪心就好了。
代码如下
#include<cmath>
#include<cstdio>
#include<algorithm>
using namespace std;
int n,d,ans;
struct xcw{
double x,y;
bool operator <(const xcw b)const{return x<b.x||x==b.x&&y<b.y;}
}a[1005];
void work(int tt){
bool anst=0;
for(int i=1;i<=n;i++){
double x,y;
scanf("%lf%lf",&x,&y);
if(y>d){anst=1;continue;}
double k=sqrt((double)d*d-y*y);
a[i].x=x-k;a[i].y=x+k;
}
if(anst){printf("Case %d: -1\n",tt);return;}
sort(a+1,a+1+n);
double lst=a[1].y;ans=1;
for(int i=2;i<=n;i++){
if(a[i].x<=lst) lst=min(lst,a[i].y);
else lst=a[i].y,ans++;
}
printf("Case %d: %d\n",tt,ans);
}
int main(){
int K=0;
for(scanf("%d%d",&n,&d);n||d;scanf("%d%d",&n,&d)) work(++K);
return 0;
}