zoukankan      html  css  js  c++  java
  • 牛客392A 经典区间覆盖

    链接:https://ac.nowcoder.com/acm/contest/392/A
    来源:牛客网

    题目描述

    月月唱歌超级好听的说!华华听说月月在某个网站发布了自己唱的歌曲,于是把完整的歌曲下载到了U盘里。然而华华不小心把U盘摔了一下,里面的文件摔碎了。月月的歌曲可以看成由1到N的正整数依次排列构成的序列,它现在变成了若干个区间,这些区间可能互相重叠。华华想把它修复为完整的歌曲,也就是找到若干个片段,使他们的并集包含1到N(注意,本题中我们只关注整数,见样例1)。但是华华很懒,所以他想选择最少的区间。请你算出华华最少选择多少个区间。因为华华的U盘受损严重,所以有可能做不到,如果做不到请输出-1。

    输入描述:

    第一行两个正整数N、M,表示歌曲的原长和片段的个数。
    接下来M行,每行两个正整数L、R表示第i的片段对应的区间是[L,R]。

    输出描述:

    如果可以做到,输出最少需要的片段的数量,否则输出-1。
    示例1

    输入

    复制
    4 2
    1 2
    3 4

    输出

    复制
    2
    示例2

    输入

    复制
    4 2
    1 1
    3 4

    输出

    复制
    -1
    示例3

    输入

    复制
    10 5
    1 1
    2 5
    3 6
    4 9
    8 10

    输出

    复制
    4

    备注:

    1LR109,1N109,1M105


    A

    区间覆盖的经典题目虽然思路很清楚,但是实现的方式也很重要,不同的实现方式的复杂度和容易出错的程度会有差别。这题中,有的是更新一个当前的最大区间,另一个是寻找下一个待找区间。第二种方式实现起来有不少细节需要注意,例如这两组数据,需要注意因为这两组数据,例如当前位置为6,需要考虑选择出下一个区间,很明显应该从这三个(【6,8】 6,6】 【7,9】)中选择最后面的【7,9】 。所以如果用第二种方式还要加一个while判断寻找合适的区间。花费了将近三小时。
    附两组样例
    18 5
    0 7
    2 18
    13 30s
    17 20
    12 21


    15 7
    7 15
    6 8
    14 26
    0 6
    2 6
    6 6
    12 12

    
    
    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <string>
    #include <queue>
    #include <list>
    #include <map>
    #include <set>
    #include <cmath>
    #include <bitset>
    #include <vector>
    #include <iomanip>
    #include <sstream>
    #include <cstdlib>
    #include <algorithm>
    using namespace std;
    typedef long long  ll;
    #define mem(A, X) memset(A, X, sizeof A)
    #define foreach(e,x) for(__typeof(x.begin()) e=x.begin();e!=x.end();++e)
    #define fori(i,l,u) for(ll (i)=(ll)(l);(i)<=(ll)(u);++(i))
    #define ford(i,l,u) for(ll (i)=(ll)(l);(i)>=(ll)(u);--(i))
    
    ll n,m;
    struct qujian{
        ll l,r;
    };
    qujian a[100005];
    bool cmp(qujian a,qujian b){
        if(a.l<b.l) return true;
        else if(a.l==b.l){
            if(a.r>=b.r) return true;
    
        }
        return false;
    }
    void solve(){
        fori(i,1,m){
            if(a[i].r>n) a[i].r=n;
            if(a[i].l<1){
                if(a[i].r>0) a[i].l=1;
                else {
                    a[i].l=n+10;
                    a[i].r=n+10;
                }
            }
        }
        sort(a+1,a+1+m,cmp);
        //fori(i,1,m) cout<<a[i].l<<","<<a[i].r<<"   ";
        //cout<<endl;
        int cnt=0;
        int cur=0;
        bool flag=true;
        int ans=-1;
        if(a[1].l!=1) flag=false;
        else {
            cur=1;
            cnt=1;
            for(int i=2;i<=m;){
    
                //cout<<"cur: a"<<cur<<" :"<<a[cur].l<<" "<<a[cur].r<<endl;
                //cout<<"i  : a"<<i<<" :"<<a[i].l<<" "<<a[i].r<<endl;
    
                if(a[i].l>=a[cur].r+2 ) {
                    if( a[cur].r<n){
                        flag=false;
                        break;
                    }
                    i++;
                } else if(a[i].r>=a[cur].r+1){
                    bool can_sel=true;
                    int nxtpos=i;
    
                    //if(i!=m && a[i+1].l<=a[cur].r+1 && a[i+1].r>a[i].r) continue;
                    int t=i+1;
                    int tmax=a[i].r;
                    while( t<=m &&a[t].l<=a[cur].r+1 ){
                        if(a[t].r>tmax) {
                            nxtpos=t;
                            tmax=a[t].r;
                            can_sel=false;
                        }
                        t++;
                    }
    
                    if(can_sel){
                        cur=i;
                        cnt++;
                        //cout<<"sel: "<<a[cur].l<<","<<a[cur].r<<endl;
                        i++;
                    }else {
                        i=nxtpos;
                        cur=i;
                        cnt++;
                        //cout<<"sel: "<<a[cur].l<<","<<a[cur].r<<endl;
                        i++;
    
                    }
                } else {
                    i++;
                }
            }
            if(a[cur].r<n) flag=false;
        }
        if(flag) ans=cnt;
        cout<<ans<<endl;
    }
    int main()
    {
      ios::sync_with_stdio(false);
      freopen("pai.in","r",stdin);
      //freopen("2wa.out","w",stdout);
      int case_cnt=1;
      while(cin>>n>>m){
          //cout<<"case"<<case_cnt++<<endl;
          fori(i,1,m){
              cin>>a[i].l>>a[i].r;
          }
          solve();
      }
    
    return 0;
    }
    View Code


  • 相关阅读:
    1
    前端必读书籍推荐
    cn
    网站爬虫优化
    es学习
    适应移动端
    chrome禁止缓存,每次都最新的
    vue 源码环境
    [Java] 设计模式之工厂系列 04 (自定义模拟 spring 读取xml文件 beanFactory)
    [Java] JDOM 读取 xml 文件 示例程序初步
  • 原文地址:https://www.cnblogs.com/paulzjt/p/10526034.html
Copyright © 2011-2022 走看看