题目链接
明显要先处理产奶时间靠前并且结束时间靠前的奶牛,这样才能使后面的奶牛接着使用同一畜栏。
首先对结构体按照开始时间升序排列。这样从0~N找时只要判断该奶牛的起始时间是否比前面每个畜栏的最小的终止时间大,如果大的话,就可以安排在其后面产奶,并且更新该畜栏的终止时间。如果小的话,则必须新开一间畜栏。
因为一直要找最小值,考虑使用优先队列(priority_queue),结束时间小的优先级高。这样比较方便找最小值。由于优先队列是按照从大到小排列 ,所以重载写法为( return a.e > b.e)。
需要注意的是两头奶牛的开始时间和结束时间相同时不能放在同一个畜栏。
参考链接
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <iostream>
#include <cmath>
#include <vector>
#include <map>
#include <stack>
#include <queue>
using namespace std;
typedef long long ll;
const int MAX=0x3f3f3f3f;
const int N=50010;
struct Cow{
int s,e,pos,num;
friend bool operator< (Cow a,Cow b)
{
return a.e > b.e;
}
}cow[N];
bool cmp1(Cow a,Cow b){
return a.s<b.s;
}
bool cmp2(Cow a,Cow b){
return a.num<b.num;
}
int ans=0;
int main(){
int n;
while(~scanf("%d",&n)){
for(int i=0;i<n;i++){
scanf("%d%d",&cow[i].s,&cow[i].e);
cow[i].num=i;
}
sort(cow,cow+n,cmp1);
priority_queue<Cow> q;
cow[0].pos=1; //特殊处理,然后加入队列
ans=1;
q.push(cow[0]);
for(int i=1;i<n;i++){ //从第二个开始考虑
Cow now=q.top();
if(cow[i].s<=now.e){
ans++;
cow[i].pos=ans;
q.push(cow[i]);
}else{
cow[i].pos=now.pos;
q.pop(); //共用挤奶器,所以删除掉
q.push(cow[i]);
}
}
printf("%d\n",ans);
sort(cow,cow+n,cmp2); //前面排序打乱了输出顺序,所以结构体中添加了num来再次排序恢复顺序
for(int i=0;i<n;i++){
printf("%d\n",cow[i].pos);
}
}
}