雷达设备问题
文章目录
- 雷达设备问题
- 前言
- 题目描述
- 题目分析
- 代码详解
- 错误案例分析:
- 思路
- 代码:
前言
对于区间合并问题,我们一般会将区间按照左端点或者是右端点进行排序,至于其中的选择要依据题目的分析,这里给大家用贪心的想法提供一个例子,帮助大家更深的了解区间合并的应用。喜欢的小伙伴可以点个赞啦!
题目描述
假设海岸是一条无限长的直线,陆地位于海岸的一侧,海洋位于另外一侧。每个小岛都位于海洋一侧的某个点上。雷达装置均位于海岸线上,且雷达的监测范为 d,当小岛与某雷达的距离不超过 d 时,该小岛可以被雷达覆盖。
我们使用笛卡尔坐标系,定义海岸线为 x 轴,海的一侧在 x 轴上方,陆地一侧在 x 轴下方。
现在给出每个小岛的具体坐标以及雷达的检测范围,请你求出能够使所有小岛都被达覆盖所需的最小雷达数目。
输入格式
第一行输入两个整数 n 和 d,分别代表小岛数目和雷达检测范围。
接下来 n 行,每行输入两个整数,分别代表小岛的 x,y 轴坐标。
同一行数据之间用空格隔开。
输出格式
输出一个整数,代表所需的最小雷达数目,若没有解决方案则所需数目输出 −1。
数据范围
1≤n≤1000, −1000≤x,y≤1000
输入样例:
3 2
1 2
-3 1
2 1
输出样例:
2
题目分析
对于每一个在规定范围内的点,我们都可以将其看成一个区间,如下图:
每个点都可以转化为这样区间
对于这样的一系列区间,我们是按照他的左端点排序还是按照他的右端点排序呢?
答案是利用 贪心的思路
我们为了用一个雷达获取更多的小岛,理所当然的应该把雷达站安排在小岛的边缘,也就是右端点,看图:
所以我们按照右端点排序;
代码详解
详细的解析都在代码注释当中啦
#include<cmath>
#include<algorithm>
#include<iostream>
using namespace std;
const int N =1e3 + 7;
typedef pair<double,double> PDD;
PDD segs[N];
int n,d;
const double INF=1e9,esp=1e-6;//这里要用double去存储
int main(){
cin>>n>>d;
for(int i=1;i<=n;i++){
int x,y;
cin>>x>>y;
if(y>d){//发现不满足要求的点马上排除
cout<<-1<<endl;
return 0;
}
double len=sqrt(d*d-y*y);
segs[i]={x+len,x-len};//这里是为了按照右端点进行排序,所以
//利用字典序的排序手段让右端点在前
}
sort(segs+1,segs+n+1);
double last=-1e9;
int cnt=0;
for(int i=1;i<=n;i++){
if(segs[i].second>last+esp){
//如果下个区间的左端点大于当前区间右端点,更新区间
last=segs[i].first;
cnt++;
}
}
cout<<cnt<<endl;
}
错误案例分析:
思路
这里的代码是没有发现需要将点转化为区间去解决问题,而是仅仅采用贪心的策略,对一个小岛的右侧端点进行找寻,但是忽略了小数位的问题,错误题解中都是int类型的数据,但是正解当中考虑了小数的情况,希望大家引以为戒。
当然,这个题解能过 4/10个数据。
代码:
#include<iostream>
#include<algorithm>
using namespace std;
const int N =1e3 + 7;
int n,d;
typedef pair<int,int> PII;
PII q[N];
int get_dis(int position,int x,int y){
return abs(position-x)*abs(position-x)+abs(y*y);
}
int main(){
cin>>n>>d;
for(int i=1;i<=n;i++){
int x,y;
cin>>x>>y;
if(y>d){
cout<<-1<<endl;
return 0;
}
q[i]={x,y};
}
sort(q+1,q+n+1);
int position=q[1].first;
int cnt=0;
for(int i=1;i<=n;i++){
while(get_dis(position,q[i].first,q[i].second)<=d*d){
position++;
}
position--;
while(get_dis(position,q[i].first,q[i].second)<=d*d && i<=n){
i++;
}
position=q[i].first;
// cout<<position<<' ';
cnt++;
i--;
}
// puts("");
cout<<cnt<<endl;
}