问题链接:Problem
问题简述:
一条水平线上有n个岛屿,雷达的覆盖范围是d,问最少需要多少个雷达可以覆盖所有岛屿?
问题分析:
本题的岛屿存在二维的平面上,所以首先应思考如何将二维的问题转换为一维的问题进而简化计算。易知岛屿最远可位于以d为半径的雷达覆盖圆周的边上,又知纵坐标,所以可求得与岛屿相距最远x坐标距离,进而可求得雷达可放置的一个x坐标区间。
知道区间后,有以下3种情况:
1.两座岛屿的区间完全重合:一个雷达必定可完全覆盖
2.两座岛屿的区间有部分重合:当雷达位于重合部分时可覆盖
3.两座岛屿的区间无重合:两个雷达才可覆盖
则原问题便转化为了区间覆盖问题。可用贪心思想,一直选取区间最小者与下者进行比较,就能求出不重合的区间数。
其他需要注意的是:
1.当岛屿与x轴的垂直距离大于d时,雷达必定无法覆盖
2.原题中的岛屿必定位于水平线上,因此y<0也可判断为无法覆盖。
AC通过的C语言程序如下:
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<queue>
#include<set>
#include<cstring>
#include<cmath>
using namespace std;
struct node{
double x;
double y;
double xl;
double xr;
}p[1005];
bool cmp(node a,node b){
return a.x<b.x;
}
int main(){
std::ios::sync_with_stdio(false);
int n;
double d;
int c=0;
while(cin>>n>>d){
c++;
if(!n&&!d){
break;
}
for(int i=0;i<n;i++){
cin>>p[i].x>>p[i].y;
double t=sqrt(d*d-p[i].y*p[i].y);
p[i].xl=p[i].x-t;
p[i].xr=p[i].x+t;
}
sort(p,p+n,cmp);
int ans=1;
double xr=p[0].xr;
for(int i=0;i<n;i++){
if(p[i].y>d||p[i].y<0){
ans=-1;
break;
}
if(p[i].xl>xr){
ans++;
xr=p[i].xr;
}
else if(p[i].xr<=xr){
xr=p[i].xr;
}
}
cout<<"Case "<<c<<": "<<ans<<endl;
}
}