挑战程序设计竞赛 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全区间 这个没数据真看不出来
对于示例 就是
排序后的区间是 1-7 3-6 6-10
最开始我们需要找到覆盖坐标1的最优区间 就是1-7
我们取了一个区间 然后找到覆盖坐标8的最优区间 就是6-10。此时取了两个区间已经覆盖了1-10的全部坐标。
答案为2
代码如下
#define _CRT_SECURE_NO_WARNINGS #include <iostream> #include <algorithm> #include <stdio.h> 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++; } //如果所有区间都在当前点之前 那就无法覆盖了 返回-1 跳出 if (r < st) { res = -1; break; } //选择区间个数加1 res++; //选择后的所有区间已经覆盖到终点或者终点之后 那就得到了答案了 if (r >= ed) { success = true; break; } //更新当前点 继续下一轮寻找可覆盖的区间 st = r + 1; i = j - 1; } if (!success) res = -1; printf("%d\n", 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驱动爱好者 服务器程序员沟通交流
如果觉得不错,欢迎点赞,你的鼓励就是我的动力
欢迎转帖 请保持文本完整并注明出处
技术博客 http://www.cnblogs.com/itdef/
B站算法视频题解
https://space.bilibili.com/18508846
qq 151435887
gitee https://gitee.com/def/
欢迎c c++ 算法爱好者 windows驱动爱好者 服务器程序员沟通交流
如果觉得不错,欢迎点赞,你的鼓励就是我的动力
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步