第一组样例
3 2
1 2
-3 1
2 1
三个岛(1,2)(-3,1)(2,1)雷达半径为2;
假设每个岛都有一个雷达
第一个岛(1,2)又因为雷达半径为2,所以雷达只能在(1,0)处
画出来很明显就发现第二个点(-3,1)不在范围内,但是第三个点(2,1)在范围内
然后再把另外的两个圆画出来
第三个点的一个可能的圆,圆心为(2,0)然后我们就可以多画几个圆,就可以发现第三个点的圆心只能在i的区域
I[i].l=x-sqrt(d*d-y*y);//圆心可以所在的最左端
I[i].r=x+sqrt(d*d-y*y);//圆心可以所在的最右端
然后我们就可以开始比较
1,只要左边的点的右端大于等于右边的点的左端,就可以共用一个雷达
2,由于右端和左端比较所以在上面的优先级大于下面
失败的情况
1,探测范围d<0
2,岛的y值大于d(可以参考前面说的第一个点)
代码
//贪心,主要弄清排序原则,,遍历的过程
//用代码实现自己的想法才行。。
#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
struct stu
{
double l,r;
}I[1005];
bool cmp(stu a,stu b)
{
//右端点从小到大排序,右端点相同时,按照左端点从大到小排序
if(a.r==b.r)
return a.l>b.l;
return a.r<b.r;
}
int main()
{
int k=1;//组
int n,d;//个数,距离
double x,y;//位置
while(cin>>n>>d && n)
{
int flag=0;
for(int i=0;i<n;i++)
{
cin>>x>>y;
I[i].l=x-sqrt(d*d-y*y);
I[i].r=x+sqrt(d*d-y*y);
if(d<y || d<0)//不够,或者半径<0
flag=1;
}
if(flag)
printf("Case %d: -1\n",k++);
else
{
sort(I,I+n,cmp);
int ans=1;
double post=I[0].r;//初始,右端点
for(int i=1;i<n;i++)
{
if(I[i].l>post)//超过上一个范围的最大值了
{
ans++;
post=I[i].r;
}
}
printf("Case %d: %d\n",k++,ans);
}
}
return 0;
}