算法1
思路:贪心,我们用半径平方减去纵坐标平方,开根号就能得到横坐标绝对值,然后在区间取一x加减刚才得到的横坐标,就能得到一个区间长度,对于这个题,求覆盖,既是求给定若干区间,最多选多少点,可使每个区间上最少选择的点
贪心策略
1:将所有点按照右端点排序
2:
情况一:如果没有一个点在区间中,则选择右端点,
情况二:点在区间中,即在区间范围内
3.cnt:表示存在cnt个互不相交的区间结果,即opt表示最优解
C++ 代码
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstdio>
using namespace std;
const int N=1010;
int n,d;
struct Segment
{
double l,r ;//左右区间
bool operator< (const Segment &t) const//重载排序
{
return r<t.r;
}
}seg[N];
int main(){
scanf("%d%d",&n,&d);
bool failed =false;
for(int i=0;i<n;i++){
int x,y;
scanf("%d%d",&x,&y);
if(y>d)failed=true;
else{
double len=sqrt(d*d-y*y);
seg[i].l=x-len,seg[i].r=x+len;
}
}
if(failed){
puts("-1");
}
else{
sort(seg,seg+n);
int cnt=0;
double last=-1e20;//x取值从负无穷开始
for(int i=0;i<n;i++)
if(last<seg[i].l){//如果小于区间左端点,
cnt++;//雷达不能覆盖,需要新增一个雷达
last=seg[i].r;//就需要重新设置一个雷达,选择新的雷达的右端点为x,x+_len得到长度
}
printf("%d\n",cnt);
}
return 0;
}