题目描述
FJ 准备分配它的 N 只奶牛 (1≤N≤2.5×10^4) 做清洁工作,他把一天分成 T(1≤T≤10^6) 个时间段,他希望每一个时间段都有奶牛在清洁,但搞清洁的奶牛数越少越好。
输入格式
第一行,两下整数 N 和 T。
接下来 N 行,每行两个整数,表示第 i 头奶牛能工作的时间段。
输出格式
使每一个时间段都有奶牛工作的最少奶牛数,如果不可能,则输出 -1。
输入输出样例
输入 #1复制
3 10 1 7 3 6 8 10
输出 #1复制
2
说明/提示
样例解释:
有 3 头奶牛,第 1 头能工作的时间段是 1∼7,即从时间 1 开始工作,时间 7 结束(时间 7 也在工作的),第 2 头是 3∼6,第 3 头是 8∼10,则只需要第 1 头和第 3 头奶牛就能使每一个时间都有奶牛工作。
//分析//
首先看题目描述,已知一天被分成了T个时间段(时间1,时间2……时间T),并且知道每只奶牛的工作开始时间和工作结束时间。我们要求出工作时间能够覆盖一天的最少奶牛数量。而如果有无法补上的空档期,就要输出-1。所以如果排序,要按开始时间排,以避免造成空档
//代码//
#include <bits/stdc++.h> //万能头文件
using namespace std;
int n,t,ans; //奶牛总数n,一天所分成的时间段总数t,工作奶牛的最小数量ans
struct q{ //通过结构体来存储每一只奶牛的工作开始时间和结束时间
int begin,end; //这样可以更清晰简单的存储
}a[25005]; //储存奶牛信息的总数组a
bool cmp(q a,q b) { //这里是按工作开始时间排序的
return a.begin<b.begin; //从小到大排序
}
int main() {
cin>>n>>t; //输入奶牛总数和时间段总数
for (int i=1;i<=n;i++) { //通过循环来输入奶牛工作区间
cin>>a[i].begin>>a[i].end;
//将开始时间和结束时间存入结构体
}
sort(a+1,a+1+n,cmp); //按开始时间从大到小排序
int ne=0,i=1,maxe; //目前工作结束时间ne(nowend),i在这里定义,就不用再下面的for循环里重新归1了,maxe(maxend)起到筛选最久工作结束时间和打标记的作用
while (ne<t) { //只要现在工作结束时间小于最后时间,就循环
maxe=-1; //先将maxe初始化为-1,这样就没有奶牛的工作结束时间小于它了
for (;i<=n&&a[i].begin<=ne+1;i++) {
//不能将i重新定义为1,因为已经工作过的奶牛没必要再工作。只要所有的奶牛没有全看过一遍并且目前在看的奶牛开始工作时间早于或等于目前工作时间加1,就循环
if (a[i].end>maxe) {//如果目前在看的奶牛工作结束时间晚于最晚结束时间
maxe=a[i].end; //将最晚结束时间更新为目前在看的奶牛工作结束时间
}
}
if (maxe==-1) { //如果循环走完maxe都还没更新
cout<<"-1"; //说明断档了,直接结束
return 0;
}
ans++; //筛选出了当前开始时间最晚下班的奶牛
ne=maxe; //将现在工作结束时间更新
}
cout<<ans; //所有时间段都覆盖了,输出答案
return 0;
}
211

被折叠的 条评论
为什么被折叠?



