集训第四周(高效算法设计)D题 (区间覆盖问题)

原题 UVA10020  :http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=19688

经典的贪心问题,区间上贪心当然是右区间越右越好了,当然做区间要小于等于当前待覆盖的位置,我们可以用一个变量begin代表当前待覆盖的区间的左值,每一次贪心成功就更新begin的值,然后再进行类似的重复动作

我之前写的版本.两次排序。

#include"iostream"
#include"cstdio"
#include"algorithm"
using namespace std;

const int maxn=100000+10;

struct node
{
    int x,y;
}a[maxn],b[maxn];

bool cmp(node a1,node a2)
{
    return a1.x<a2.x;
}

bool cm(node a1,node a2)
{
    return a1.y>a2.y;
}

int main()
{
    int T,t;
    cin>>T;
    t=T;
    while(T--)
    {
     if(T!=t-1) cout<<endl;
      int M,f,l,r,x,a1,b1;
     cin>>M;
     f=0;
     while(cin>>a[f].x>>a[f].y&&(a[f].x||a[f].y))
     {
       if((a[f].x<0&&a[f].y<0)||(a[f].x>M&&a[f].y>M))
       continue;
       f++;
     }
 //    cout<<f<<endl;
     sort(a,a+f,cmp);

     if(a[0].x>0||f==0) cout<<0<<endl;

     else
     {

     sort(a,a+f,cm);
     int ff=0,flag=0,sum=0,begi;
     begi=0;
     while(begi<M)
     {
      for(int i=0;i<f;i++)
      {
         if(a[i].x>begi) continue;
         if(a[i].y==begi) continue;
         begi=a[i].y;flag=1;sum++;b[sum].x=a[i].x;b[sum].y=a[i].y;break;
      }
    //cout<<begi<<endl;getchar();
      if(flag)
      {
          flag=0;
      }
      else
          {ff=1;break;}
     }
    if(ff) cout<<0<<endl;
    else {
            cout<<sum<<endl;
            for(int i=1;i<=sum;i++)
                    cout<<b[i].x<<' '<<b[i].y<<endl;
         }
     }
    }
    return 0;
}

也可以只排序一次,这样的话需要记录当前已贪心到的数组下标位置,可以摒弃掉那些已经遍历过的那些数组元素,也是一样的时间

#include"iostream"
#include"cstdio"
#include"algorithm"
using namespace std;

const int maxn=100000+10;

struct node
{
    int x,y;
}a[maxn],b[maxn];

bool cmp(node a1,node a2)
{
    return a1.x<a2.x;
}

bool cm(node a1,node a2)
{
    return a1.y>a2.y;
}

int main()
{
    int T,t;
    cin>>T;
    t=T;
    while(T--)
    {
     if(T!=t-1) cout<<endl;
     int M,f;
     cin>>M;
     f=0;
     while(cin>>a[f].x>>a[f].y&&(a[f].x||a[f].y))
     {
       if((a[f].x<0&&a[f].y<0)||(a[f].x>M&&a[f].y>M))
       continue;
       f++;
     }

     sort(a,a+f,cmp);

     if(a[0].x>0||f==0) cout<<0<<endl;

     else
     {
     int ff=0,sum=0,begi,r;
     begi=0;r=-1;
     int i=0,j;
     while(i<f)
     {
         j=i;
      while(a[j].x<=begi &&j<f)
      {
          if(r<a[j].y) 
           {
          r=a[j].y;
          b[sum].x=a[j].x;
          b[sum].y=a[j].y;
           }
          j++;
      }
      if(j==i) break;
      i=j;
      sum++;
      begi=r;
      if(begi>=M) {ff=1;break;}
     }
    if(ff==0) cout<<0<<endl;
    else {
            cout<<sum<<endl;
            for(int i=0;i<sum;i++)
                    cout<<b[i].x<<' '<<b[i].y<<endl;
         }
     }
    }
    return 0;
}
原文地址:https://www.cnblogs.com/zsyacm666666/p/4704867.html