题目描述
程序员PIPI有许多电脑,他每天要用这些电脑处理许多个进程,每个进程有开始于第S天,结束于第 T天 (即进程的执行区间为[S,T] ),这些进程需要一些电脑来进行处理。
每一个进程只需要在 S≤d≤T的任意一天d进行处理即可 , 值得注意的是,PIPI的电脑每天只能处理一个进程。现在有n个进程到了PIPI手上,PIPI想知道他最多能够处理多少个进程?
输入
输入包含多组测试用例。
对于每组样例,第一行包含一个正整数 n (n<=1e5),代表进程的数目。
接下来n行每行输入进程的开始时间 S 和结束时间 T, (0<=S<=T<=1e5)。
输出
对于每组样例,输出PIPI最多可以处理多少个进程。
样例输入
3
1 2
2 3
3 4
4
1 2
2 3
3 4
1 2
5
1 4
4 4
2 2
3 4
1 1
样例输出
3
4
4
提示
对于样例1: 可以在第一天处理[1,2] 第二天处理[2,3] 第三天处理[3,4]
对于样例2: 可以在第一天处理[1,2] 第二天处理[1,2] 第三天处理[2,3] 第四天处理[3,4]
#include <bits/stdc++.h>
using namespace std;
const int INF=1E9;
struct node
{
int x,y;
}E[100005];
bool cmp(node a,node b)
{
if(a.x==b.x)
return a.y<b.y;
else
return a.x<b.x;
}
int n;
int main()
{
while(scanf("%d",&n)!=EOF)
{
int ans=-INF;
for(int i=0;i<n;i++)
{
int u,v;
scanf("%d%d",&u,&v);
E[i].x=u,E[i].y=v;
ans=max(ans,v);
}
sort(E,E+n,cmp);
priority_queue<int,vector<int>,greater<int> >q;
int now=0,pos=0,sum=0;
while(now<=ans)
{
while(pos<n&&E[pos].x<=now) ///用pos来记录当前访问到的时间段,并且不会回溯,实现的结构很巧妙 要牢记
{
q.push(E[pos++].y);
}
while(q.size()) ///当队列非空的时候,弹出结束时间最早的结点
{
int end_time=q.top();
q.pop();
if(end_time<now)
continue;
sum++;
break;
}
now++;
}
printf("%d\n",sum);
}
return 0;
}
方法2
不用枚举天数
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
struct node{
int x,y;
}E[N];
bool cmp(node a,node b){
return a.x<b.x;
}
priority_queue<int,vector<int>,greater<int> >q; ///小顶堆将结束的时候从小到大排序
int main(){
int n;
while(scanf("%d",&n)!=EOF){
for(int i=0;i<n;i++){
scanf("%d%d",&E[i].x,&E[i].y);
}
int day;
sort(E,E+n,cmp);
int i,ans;
for(i=0,ans=0;i<n||q.size();){
if(!q.size()){
q.push(E[i].y);
day=E[i++].x;
}
while(i<n&&E[i].x<=day){ ///开始时间相等的情况
q.push(E[i++].y);
}
if(q.top()>=day){
ans++;
day++;
}
q.pop();
}
printf("%d\n",ans);
}
}