>link
>解题思路
以奶牛开始吃草时间排序
- 如果当前奶牛可以接到一个畜栏后面,就往上接
- 如果没有一个畜栏可以接,就为这头奶牛新建一个畜栏
可以发现,只要畜栏的最后一头奶牛结束吃草时间越早,接上奶牛的可能性就越大
用小根堆,以畜栏的结束吃草时间实时排序
>Code
#include <algorithm>
#include <iostream>
#include <cstdio>
#include <queue>
using namespace std;
struct DT {
int x, y, i;
} a[50100], t;
int n, ans[50100], num;
bool cmp(const DT& k, const DT& l) {
if (k.x == l.x)
return (k.y < l.y);
return (k.x < l.x);
}
//小根堆用结构体的用法(我也不懂为什么这么写)
bool operator<(DT a, DT b) {
return a.y > b.y; }//以结束吃草时间排序
//return a.y < b.y; 就是大根堆了,好奇妙
int main() {
scanf("%d", &n);
for (int i = 1; i <= n; i++) {
scanf("%d%d", &a[i].x, &a[i].y);
a[i].i = i;
}
sort(a + 1, a + 1 + n, cmp);
priority_queue<DT> f;
f.push(a[1]), ans[a[1].i] = ++num;//ans标记在哪个畜栏里
for (int i = 2; i <= n; i++) {
t = f.top();
if (a[i].x <= t.y)//如果最早吃完的畜栏也接不上这头牛
f.push(a[i]), ans[a[i].i] = ++num;//新建一个畜栏
else {
//接的上就往上接
f.pop();
t.y = a[i].y, ans[a[i].i] = t.i;//更新这个畜栏的结束吃草时间
f.push(t);
}
}
printf("%d\n", f.size());
for (int i = 1; i <= n; i++) printf("%d\n", ans[i]);
}