• 集训第四周(高效算法设计)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;
    }
  • 相关阅读:
    网页特殊符号HTML代码大全
    检测手机类型正则表达式
    blur和focus的运用
    腾讯对外分享组件接口文档
    js 类型检测
    iconfont的应用
    运算符优先级 (JavaScript)
    IOC(控制反转)和DI(依赖注入)
    Mybatis的运行原理
    通用Mapper
  • 原文地址:https://www.cnblogs.com/zsyacm666666/p/4704867.html
Copyright © 2020-2023  润新知