C. 【例题3】畜栏预定
题目链接
内存限制:256 MiB
时间限制:1000 ms
标准输入输出
题目类型:传统
评测方式:Special Judge
题目描述
有 n 头牛在畜栏中吃草。每个畜栏在同一时间段只能提供给一头牛吃草,所以可能会需要多个畜栏,给出第 i 头牛开始吃草的时间区间 [ a i , b i ] [a_i,b_i] [ai,bi] ,求需要的最少畜栏数和每头牛对应的畜栏方案。
输入格式
第一行一个正整数 n。
接下来 n 行,第 i 行两个正整数 a i , b i a_i,b_i ai,bi。
输出格式
第一行一个整数n,表示需要的最少畜栏数。
接下来 n 行,第 i 行一个整数表示第 i 头牛的对应畜栏,编号是从 1 开始的连续整数,方案合法即可。
样例
样例输入
5
1 10
2 4
3 6
5 8
4 7
样例输出
4
1
2
3
2
4
数据范围与提示
对于 % 100 \%100 %100 的数据,有 1 ≤ N ≤ 5 × 1 0 4 , 1 ≤ a i , b i ≤ 1 0 6 1\leq N\leq5×10^4,1\leq a_i,b_i\leq10^6 1≤N≤5×104,1≤ai,bi≤106。
题解
牛按
a
i
a_i
ai排序,再依次枚举,
对于每一头牛,若当前没有可用畜栏,则新加一个畜栏;
若有,则用,并维护这个畜栏的牛吃草的结束时间。
可用小根堆来找出吃草结束时间最早的畜栏,
于是时间复杂度可优化成
O
(
n
log
n
)
O(n\log n)
O(nlogn)
代码
#include<iostream>
#include<algorithm>
#include<queue>
#include<cmath>
#define ll long long
using namespace std;
ll n,ans[100001];
struct que
{
ll r;
ll id;
bool operator < (const que &a) const
{
return r>a.r;
}
};
priority_queue <que> q;
struct node
{
int l,r,id;
} a[100001];
ll cmp(node x,node y)
{
return x.l<y.l;
}
int main()
{
cin>>n;
for(int i=1; i<=n; i++)
{
cin>>a[i].l>>a[i].r;
a[i].id=i;
}
sort(a,a+n+1,cmp);
for(int i=1; i<=n; i++)
{
if(!q.size()||q.top().r>=a[i].l)//若没有可用畜栏,新加畜栏
{
ans[a[i].id]=q.size()+1;
q.push((que){a[i].r,q.size()+1});
}
else
{
ans[a[i].id]=q.top().id;
q.pop();
q.push((que){a[i].r,ans[a[i].id]});
}
}
cout<<q.size()<<endl;
for(int i=1; i<=n; i++)
{
cout<<ans[i]<<endl;
}
}