UVA - 10382

由图可知,我们可以将圆与草坪上限的两个交点看成这个圆圆所能覆盖到的范围,所以思路为

求出每个圆左右交点,因为要求出最少用到的圆,所以可以按照每个圆的左交点从小到大排序,从左到右选择所需要的圆;

注意:

第一个圆的左端点如果不能小于等于零,直接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;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值