AcWing 112. 雷达设备
逆向思维,通过岛屿来确定能放置雷达的范围,这样就将问题转化成区间的贪心问题了。
第一种
- 将每个区间按右端点升序排序。
- 当上个雷达所在的位置小于当前区间的左端点时就需要增加一个雷达放在右端点。
- 否则就不用添加雷达
#include<iostream>
#include<cmath>
#include<algorithm>
using namespace std;
const int N = 3010, eps = -1e6;
struct Seg{
double l,r;
bool operator < (const Seg& t) const{
return r < t.r;
}
}seg[N];
int main(){
cin.tie(0)->sync_with_stdio(false);
cout.tie(0);
int n,d; cin>>n>>d;
bool flag = true;
for(int i = 0; i < n; i++){
int x,y; cin>>x>>y;
if(y > d){
flag = false;
break;
}
double len = sqrt(d*d-y*y);
seg[i] = {x-len,x+len};
}
if(flag){
int ans = 0;
sort(seg,seg+n);
double last = -0x3f3f3f3f;
for(int i = 0; i < n; i++){
if(last < seg[i].l){
ans ++;
last = seg[i].r;
}
}
cout<<ans;
} else puts("-1");
return 0;
}
第二种
- 将区间按左端点降序排序
- 每次贪心选择最左端
#include<iostream>
#include<cmath>
#include<algorithm>
using namespace std;
const int N = 3010, eps = -1e6;
struct Seg{
double l,r;
bool operator < (const Seg& t) const{
return l > t.l;
}
}seg[N];
int main(){
cin.tie(0)->sync_with_stdio(false);
cout.tie(0);
int n,d; cin>>n>>d;
bool flag = true;
for(int i = 0; i < n; i++){
int x,y; cin>>x>>y;
if(y > d){
flag = false;
break;
}
double len = sqrt(d*d-y*y);
seg[i] = {x-len,x+len};
}
if(flag){
int ans = 0;
sort(seg,seg+n);
double left = 0x3f3f3f3f;
for(int i = 0; i < n; i++){
if(left > seg[i].r){
ans ++;
left = seg[i].l;
}
}
cout<<ans;
} else puts("-1");
return 0;
}