uva 10382 贪心 区间覆盖问题

#include"stdio.h"
#include"cmath"
#include"algorithm"
#include"iostream"
using namespace std;
struct sgm
{
    double l;
    double r;
    friend bool operator < (const sgm&a,const sgm&b){
        if(a.l < b.l) return 1;
        else if(a.l==b.l&&a.r>b.r) return 1;
        else return 0;
    }
}a[10000+500];
int main()
{

    //freopen("b.in","r",stdin);
    //freopen("b.out","w",stdout);
    int n;
    double l,w;
    while(cin>>n>>l>>w)
    {
        double x,r;
        int cnt=0;
        for(int i=0;i<n;i++)
        {
            scanf("%lf%lf",&x,&r);
            if(r<=w/2.0) continue;
            double t=sqrt(r*r-w*w/4.0);
            double Start=x-t,End=x+t;
            if(Start<0) Start=0;if(End>l) End=l;
            a[cnt].l=Start;a[cnt++].r=End;
        }
        sort(a,a+cnt);
        if(cnt==0||a[0].l>0) {cout<<-1<<endl;continue;}
        double fuck=-1;
        int i,j;
        double Max;int Maxj;
        double left=0,right=0;
        int ans=0;
        for(i=0;i<cnt;)
        {
            for(j=i;a[j].l<=left&&j<cnt;j++)//从起点之后开始搜索相同起点下最远距离max(a[j].r)的边
                if(a[j].r>right) right=a[j].r;
            if(i==j) break; //没有边能加入了

            ans++;
            i=j;
            left=right;  //更新起点
            
            //cout<<"right----"<<right<<endl;
            if(right==l) break;
        }

        if(right!=l) cout<<-1<<endl;
        else cout<<ans<<endl;
    }
    return 0;
}



#include"stdio.h"
#include"cmath"
#include"algorithm"
#include"iostream"
using namespace std;
struct sgm //线段 l起点 r终点
{
    double l;
    double r;
    friend bool operator < (const sgm&a,const sgm&b){
        if(a.l < b.l) return 1;
        else if(a.l==b.l&&a.r>b.r) return 1;
        else return 0;
    }
}a[10000+500];
int main()
{

    //freopen("b.in","r",stdin);
    //freopen("b.out","w",stdout);
    int n;
    double l,w;
    while(cin>>n>>l>>w)
    {
        double x,r;
        int cnt=0;
        for(int i=0;i<n;i++)
        {
            scanf("%lf%lf",&x,&r);
            if(r<=w/2.0) continue;
            double t=sqrt(r*r-w*w/4.0);
            double Start=x-t,End=x+t;
            if(Start<0) Start=0;if(End>l) End=l;
            a[cnt].l=Start;a[cnt++].r=End;
        }
        sort(a,a+cnt);
        if(cnt==0||a[0].l>0) {cout<<-1<<endl;continue;}
        double Start,End;
        int maxj=-1;
        double left=0,right=0; //left起点 当在相同起点下找到最长边的终点 更新 为下一次枚举的起点
        int ans=0;     //加入了几条边
        int i,j; //第一次枚举时候因为一条边都没有,i=0开始枚举,当加入过边之后,就从加入的那条边之后的枚举
        for(i=0;i<cnt;) //起边(当边的起点)//枚举时候就从这条边开始
        {
            for(j=i;j<cnt&&a[j].l<=left;j++)  //从起边开始枚举  边的左端点点小于等于起点当成一类边处理取出右端点最大的边
            {
                if(a[j].r>right) right=a[j].r;//相同类型中取出右端点最大的
            }

            if(j==i) break; //当上面的循环无法进行的时候说明已经没有边可以加入了

            i=j;     //下一次枚举时候从 刚加入的那条边之后的边 开始枚举

            left=right; //更新起点
            ans++;      //更新一次相当于向区间加入一条边
            if(right==l) break; //当覆盖区域达到l退出循环
        }
        if(right==l) cout<<ans<<endl;
        else cout<<-1<<endl;
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值