zoukankan      html  css  js  c++  java
  • Cleaning Shifts(区间覆盖)

    /*

    题目:

    给定一个时间T和N个时间区间,求最少需要多少个区间覆盖总区间[1,T],无法覆盖区域[1,T]时输出-1。

    例如T=10,有3个区间[1,7],[3,6],[8,10],则最少需要两个区间来覆盖,选择区间1和区间3。

    解题思路:

    使用贪心法。首先将区间按开始时间从小到大排序,开始时间相等按结束时间从小到大排序。

    1 如果第一个区间不是从1开始,则无法覆盖,输出-1。

    2 令当前覆盖到的时间time为开始时间为1的区间中结束时间的最大值。

    3 从开始时间不为1的区间开始循环遍历。

    4 选择合法区间中结束时间值最大的那个区间,合并到[1,time],合并后time为选择的区间的结束时间。所谓合法区间是指区间的起始时间start<=time+1,这样才能和区间[1,time]合并。如果没有找到合法区间或者找到的区间结束时间比time小,则无法覆盖,结束循环。

    5 循环结束后,根据time是否大于等于T,输出结果。

    */
     
     
     
    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    struct qujian
    {
        int left;
        int right;
    };
    bool comp(qujian a,qujian b)
    {
        if(a.left==b.left)return a.right<b.right;
        return a.left<b.left;
    }
    int main()
    {
        int N,End;
        scanf("%d%d",&N,&End);
        struct qujian q[N+1];
        for(int i=1; i<=N; i++)
            scanf("%d%d",&q[i].left,&q[i].right);
        sort(q+1,q+N+1,comp);
        if(q[1].left>1)printf("-1 ");//肯定覆盖不了
        else
        {
            int temp=q[1].right,max=q[1].right;
            int count=1;
            int i=1;
            while(max<End)
            {
     
                if(q[i].left>max+1)i++;//此判断条件是为了防止与下面的i++重复,否则就会加两次了,
                if(i>N)break;//如果检索到结尾就结束
                // cout<<"max="<<max<<endl;
                if(max>=End) break;//即已经找到,可以覆盖了
                count++;//找到的区间个数
                while(q[i].left<=max+1)//[1,3] [4,6]视为连续的
                {
                    if(temp<q[i].right)
                        temp=q[i].right;//满足条件下找到结尾最大的
                    if(temp>=End)//已经覆盖,可以结束
                        break;
                    i++;//依次向后寻找
                    if(i>N)break;
                }
                 max=temp;//记录最大的结尾
            }
            if(temp<End)printf("-1 ");//找完后仍不能覆盖
            else
                printf("%d ",count);
        }
        return 0;
    }
    /*
    4 10
    3 10
    1 2
    4 10
    10 11
     
    */
    /*
    3 10
    1 7
    3 6
    6 10
    */
    /*
    4 10
    1 10
    3 5
    4 8
    6 10
    */
    梦里不知身是客,一晌贪欢。
  • 相关阅读:
    JAVA for(i = 0; i<a.length; i++) 解析
    3.2.2多维数组 3.3 排序
    3.2数组
    字符串和数组
    2.7.3与程序转移有关的跳转语句
    2.7.2 循环语句
    读书共享 Primer Plus C-part 4
    Linux 批量修改文件名
    关于/usr/local/lib/libz.a(zutil.o): relocation R_X86_64_32 against `.rodata.str1.1' can not be used when making a shared object; recompile with -fPIC解决办法
    做一个有深度的程序猿
  • 原文地址:https://www.cnblogs.com/dccmmtop/p/4975345.html
Copyright © 2011-2022 走看看