雷达安装
描述
描述:
假设海岸线是一条无限延伸的直线。它的一侧是陆地,另一侧是海洋。每一座小岛是在海面上的一个点。雷达必须安装在陆地上(包括海岸线),并且每个雷达都有相同的扫描范围d。你的任务是建立尽量少的雷达站,使所有小岛都在扫描范围之内。
数据使用笛卡尔坐标系,定义海岸线为x轴。在x轴上方为海洋,下方为陆地。
样例1如图所示
输入
第一行包括2个整数n和d,n是岛屿数目,d是雷达扫描范围。
接下来n行为岛屿坐标。
输出
一个整数表示最少需要的雷达数目,若不可能覆盖所有岛屿,输出“-1”。
样例
3 2
1 2
-3 1
2 1
2
难度
中,贪心算法
解法
根据光路可逆(大雾),岛能看到你,你也就能看到岛。
先处理出每个岛 (x,y) 能看到的坐标轴的范围,根据勾股定理容易得出(x-len,x+len)
这样我们就得到了 n 个区间,要保证每个区间内有一个雷达。
这就是 区间选点 问题。
我们再按最小区间覆盖的做法,将右端点从小到大排序,然后取点,结束。
代码
#include<bits/stdc++.h>
using namespace std;
struct range{
double x;
double y;
double xrange1;
double xrange2;
};
int comparison(range a, range b){
return a.xrange2 < b.xrange2;
}
void work()
{
int n,d,count=1;
cin>>n>>d;
vector<range> xrange;
int x,y;
for(int i=0;i<n;i++) {
range ii;
cin >> ii.x >> ii.y;
if(ii.y>d || ii.y<-d){
cout<<"-1"<<endl;
return;
}
ii.xrange1 = ii.x-sqrt(d*d-ii.y*ii.y);
ii.xrange2 = ii.x+sqrt(d*d-ii.y*ii.y);
xrange.push_back(ii);
}
sort(xrange.begin(),xrange.end(),comparison);
double position = xrange[0].xrange2;
for(int i=1;i<n;i++){
if(position>=xrange[i].xrange1)
continue;
else{
count++;
position = xrange[i].xrange2;
}
}
cout<<count<<endl;
}
int main() {
work();
return 0;
}