由图可知,我们可以将圆与草坪上限的两个交点看成这个圆圆所能覆盖到的范围,所以思路为:
求出每个圆左右交点,因为要求出最少用到的圆,所以可以按照每个圆的左交点从小到大排序,从左到右选择所需要的圆;
注意:
第一个圆的左端点如果不能小于等于零,直接pass,然后开始从左至右找,设p=k,为第一个圆的右端点,开始判断下一个圆的左端点,直到大于p为止,此期间k的值一直与下一个圆的右端点比较,取最大值,最后再让p=k;当p>草坪长度或者判断完所有的圆,结束查找;最后要判断p是否大于等于草坪长度。
代码如下:
#include<stdio.h>
#include<math.h>
#include<iostream>
#include<algorithm>
using namespace std;
struct node
{
double ri,o;
double l,r;
} q[10010];
bool cmp(node a,node b)
{
return a.l<b.l;
}
int main()
{
double l, w;
int n;
while(~scanf("%d%lf%lf",&n,&l,&w))
{
w=w/2;
double dis;
int m=0;
for(int i=0; i<n; i++)
{
scanf("%lf%lf",&q[m].o,&q[m].ri);
if(q[m].ri<=w)
continue;
dis=sqrt(q[m].ri*q[m].ri-w*w);
q[m].l=q[m].o-dis;
q[m].r=q[m].o+dis;
m++;
}
sort(q,q+m,cmp);
if(q[0].l>0)
{
printf("-1\n");
continue;
}
int i=0;
double k=0,p=0;
int f=0,cnt=0;
while(i<m)
{
int j=i;
while(q[i].l<=p&&i<m)//4
{
if(k<q[i].r)//最 远的 圆
k=q[i].r;
i++;
}
if(j==i)//2 相离 之后都没有满足的了
{
f=1;
break;
}
p=k;
cnt++;//--------------------
if(k>=l)
break;
// if(q[i].r>k&&i<m)
// {
// if(q[i].l>p)//2 相离 之后都没有满足的了
// {
// f=1;
// i=0x3f3f3f;
// break;
// }
// }
}
if(k<l)
{
printf("-1\n");
continue;
}
if(!f)
printf("%d\n",cnt);
else
printf("-1\n");
}
return 0;
}