题意:
海岸上有雷达可以辐射以d为半径的半圆区域,海岸之外还有岛屿,要求用最少的雷达个数覆盖所有的岛屿。
思路:
一开始画图的时候,一直是画雷达的辐射范围去想怎么贪心使得覆盖面积最大,一直卡着,其实可以换个角度,从岛屿的角度考虑雷达的区域只要以岛屿为中心的圆与海岸线的相交线(下图ab)中有一个雷达即可,所以问题就转化为在所有这样的ab区域内都有一个点,总的点数目还要最少。
贪心策略:
将所有区间(ab)按右端点从小到大排序;
依次考虑每个区间:
如果当前区间包含最后一个选择的点,则直接跳过;
如果当前区间不包含最后一个选择的点,则在当前区间的右端点的位置选一个新的点;
AC代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e5+10;
typedef pair<double,double>PDD;
PDD seg[maxn];
int main()
{
int n,d;
cin>>n>>d;
bool flag = true;
for(int i=1;i<=n;i++) {
int x,y;
cin>>x>>y;
if(y>d) flag = false;
double len = sqrt(d*d-y*y);
seg[i] = {x+len,x-len};
}
if(!flag) cout<<"-1"<<endl;
else {
sort(seg+1,seg+1+n);
int res = 0;
double last = -0x3f3f3f3f;
for(int i=1;i<=n;i++) {
if(seg[i].second>last) {
res++;
last = seg[i].first;
}
}
cout<<res<<endl;
}
}