题目大意
给定n个区间, 你需要找一些点, 放在区间中,同一个点可以放在几个区间中
但是这些区间不能有交集
求一共需要多少个点,并输出任意一个合法方案
样例
Sample Input
5
1 10
2 4
3 6
5 8
4 7
Sample Output
4
1
2
3
2
4
思路
- 把区间按照左端点从小到大排序,然后遍历区间,把第一个区间放入优先队列,优先队里对顶存的是放进去区间的右端点,小的在队顶,
- 遍历区间时,把队列里的对顶元素与当前区间比较,如果对顶元素比当前区间的左端点大,就没有满足的点,此时就再创建一个点,然后加入队列,最后队列的size就是点的总数
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <queue>
using namespace std;
const int N = 50010;
struct node {
int cow, id;
bool operator<(const node &a) const{
return cow > a.cow;
}
};
struct node2 {
int l;
int r;
int pos;
bool operator<(const node2 &a) const{
if(l != a.l)
return l < a.l;
return r < a.r;
}
};
int id[N];
node2 cows[N];
int n;
int main()
{
priority_queue<node> q;
scanf("%d", &n);
for(int i = 1; i <= n; i++)
{
int l, r;
scanf("%d%d", &l, &r);
cows[i].l = l;
cows[i].r = r;
cows[i].pos = i;
}
sort(cows + 1, cows + n + 1);
for(int i = 1; i <= n; i++)
{
node t;
if(q.empty() || q.top().cow >= cows[i].l)
{
t.cow = cows[i].r;
t.id = q.size() + 1;
id[cows[i].pos] = t.id;
q.push(t);
}
else
{
t = q.top();
q.pop();
t.cow = cows[i].r;
id[cows[i].pos] = t.id;
q.push(t);
}
}
printf("%d\n", q.size());
for(int i = 1; i <= n; i++)
{
printf("%d\n", id[i]);
}
return 0;
}