UVa:10020 Minimal coverage

 

区间覆盖问题,书上有分析但还是用了好久才AC掉。

 

用贪心法,依据每条线段的起点排序,依次扫描在线段起点小于等于区间左端点(初始为0)的前提下,选取有效长度最长(即线段终点最大)的那条线段的终点作为新区间的起点,然后继续像开始那样扫描直至所得线段终点大于等于区间右端点。

 

线段尽量长才能保证覆盖区间尽量大,才使得所用线段尽量少,这是贪心的关键。

 

我写的代码中有一些细节需要注意。
比如说确定最大有效长度的过程是使用了一个新的循环,结束循环的条件是出现起点小于区间左端点的线段。

 

 

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<algorithm>
using namespace std;
struct Segment
{
    int l,r;
};
Segment x[100005]={0};
bool cmp(Segment a,Segment b)
{
    return a.l<b.l;
}
int main()
{
 // freopen("in.txt","r",stdin);
    int T;
    scanf("%d",&T);
    while(T--)
    {
      int m,n=0;
      int a,b;
      scanf("%d",&m);
      while(scanf("%d%d",&a,&b)==2&&!(!a&&!b))
      {
          if(b<=0||a>=m) continue;
          x[n].l=a;
          x[n++].r=b;
      }
      sort(x,x+n,cmp);
     int y[100005]={0};
     int L=0,t=0,max=0,count=0;
          for(int i=0;i<n;++i)
         {
            if(x[i].r<=L) continue;
            if(x[i].l<=L)
            {
              int j;
              for(j=i;j<n;j++)
              {
                  if(x[j].l<=L&&x[j].r>max) {max=x[j].r;t=j;}
                  if(L<x[j].l) break;
              }
                L=max;
                y[count++]=t;
              if(L>=m) break;
            }
         }
      if(L<m||x[0].l>0) count=0;
      printf("%d\n",count);
      for(int i=0;i<count;i++)
      printf("%d %d\n",x[y[i]].l,x[y[i]].r);
      if(T) printf("\n");
    }
    return 0;
}


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值