题目的意思就是给你一个坐标轴,雷达在x轴上,岛屿分布在x轴上方,给你岛屿的坐标以及雷达的最大扫描面积,求最少用几个雷达可以将所有的岛屿覆盖!
以每个点为圆形,d为半径做圆,圆与x轴的两个交点分出一个区间,雷达在区间内可以辐射到该点,转化为每个区间内至少有一个雷达的区间选点问题。
利用贪心的思想,将区间以右端点排序,从小到大循环,如果该区间没有雷达则在区间右端点安放雷达。
证明可参考csdn
#include<iostream>
#include<cmath>
#include<algorithm>
using namespace std;
const int N = 1010;
int n,d,idx;
struct stu//结构体存区间两端点
{
double l,r;//有根号运算要用double
} a[N];
bool cmp(stu q,stu e)
{
return q.r < e.r;
}
int main()
{
while(cin>>n>>d,n || d)
{
idx ++;
bool flag = false;
int x,y;
for(int i = 0; i < n; i ++ )
{
cin>>x>>y;
if(y > d)//纵坐标大于d说明雷达无法辐射到输出-1
flag = true;
double t = sqrt((double) d * d - y * y);//勾股定理
a[i].l = (double) x - t;//区间两端点
a[i].r = (double) x + t;
}
if(flag)
cout<<"Case "<<idx<<": "<<-1<<endl;
else
{
sort(a,a + n,cmp);
int res = 1;//第一个区间右端点一定有一个雷达
double x = a[0].r;//上一个雷达的位置
for(int i = 1; i < n; i ++ )
if(a[i].l > x)
{
res ++ ;
x = a[i].r;
}
cout<<"Case "<<idx<<": "<<res<<endl;
}
}
return 0;
}