挑战程序设计竞赛 2章习题 poj 2376 Cleaning Shifts

地址  http://poj.org/problem?id=2376

题目大意是 给出 N个区间 ,询问最小需要选择几个区间能覆盖 1~T的全部区间
第一行输入 N和 T
后面N行 每行2个数字 表示区间的起点和终点
要求输出一行 选择的最小区间个数 若无法覆盖全部区间 则输出-1

Sample Input
3 10
1 7
3 6
6 10
Sample Output
2

解法 

贪心  将所有区间按照起点排序

选择能覆盖当前点且结束最迟的区间 然后更新当前点到选择的区间最迟的坐标 继续选择

本来以为是一个区间覆盖的模版题,结果wa了一下午,poj没有数据提,偏偏样例还能过

看了别人的题解才发现 1~5 6~10居然也算是覆盖了1~10全区间  这个没数据真看不出来

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <algorithm>

using namespace std;

const int N = 1000010;

/*
Sample Input

3 10
1 7
3 6
6 10
Sample Output

2
*/
int n;
struct Range
{
    int l, r;
    bool operator< (const Range &W)const
    {
        return l < W.l;  
    }
}range[N];

int main()
{
    int st, ed;
    scanf("%d%d", &n, &ed);
    st = 1;
    for (int i = 0; i < n; i++)
    {
        int l, r;
        scanf("%d%d", &l, &r);
        range[i].l=l;range[i].r=r; 
    }

    sort(range, range + n);

    int res = 0;
    bool success = false;
    for (int i = 0; i < n; i++)
    {
        int j = i, r = -2e9;
        while (j < n && range[j].l <= st)
        {
            r = max(r, range[j].r);
            j++;
        }

        if (r < st)
        {
            res = -1;
            break;
        }

        res++;
        if (r >= ed)
        {
            success = true;
            break;
        }

        st = r+1;
        i = j - 1;
    }

    if (!success) res = -1;
    printf("%d
", res);

    return 0;
}
作 者: itdef
欢迎转帖 请保持文本完整并注明出处
技术博客 http://www.cnblogs.com/itdef/
B站算法视频题解
https://space.bilibili.com/18508846
qq 151435887
gitee https://gitee.com/def/
欢迎c c++ 算法爱好者 windows驱动爱好者 服务器程序员沟通交流
如果觉得不错,欢迎点赞,你的鼓励就是我的动力
阿里打赏 微信打赏
原文地址:https://www.cnblogs.com/itdef/p/14574439.html