传送门
题目描述:
今年是石室中学 2160 2160 2160 年校庆年。CCTV 国家宝藏节目联合中国国家图书馆赠送给学校一份珍贵的礼物——蜀石经拓本的复制本,让蜀石经重回石室。
同学们听说了这个消息后,纷纷希望一睹真容。学校在校史馆展出了这件国宝,今天有 n n n 个同学去参观,排起了长龙。因为学习紧张时间宝贵,我们决定让每个同学登记自己的时间安排。
你现在拿到了这份时间表,知道了对于第 i i i 个同学,他计划在 a i a_i ai 时间来看到这件国宝,他的欣赏时间为 t i t_i ti,他在欣赏的时间段中其他到达的同学智能排队等待,当一个人欣赏完后,有多个同学在等待,就会让操行分高的学生先欣赏(一个人恰好在一个人欣赏完离开时到达也认为是在等待)。当然,如果一个时间点没有任何人在欣赏,但同时有多个人是同一时间到,也是按操行分最高的先欣赏。
请你计算出所有同学在队伍中等待的时间(即对于 i i i,等待时间为 a i a_i ai 到他开始欣赏的时间)的最大值。
输入格式:
输入的第一行包含 n n n。
以下 n n n 行按操行分高到低的顺序给出了 n n n( 1 ≤ n ≤ 1 0 5 1\le n\le10^5 1≤n≤105)个同学的时间安排 。每行包含一个人的 a i a_i ai 和 t i t_i ti。
所有的 t i t_i ti 为不超过 1 0 4 10^4 104 的正整数,所有的 a i a_i ai 为不超过 1 0 9 10^9 109 的正整数。
输出格式:
输出所人中的最长等待时间。
样例数据:
输入
5
25 3
105 30
20 50
10 17
100 10
输出
10
提示:
【样例解释】
一共有 5 5 5 个人,第 4 4 4 个人最先到(时间 10 10 10),第一个欣赏。
4 4 4 欣赏完(时间 27 27 27)后,第 1 1 1 和 3 3 3 个人都到达了,由于第一个人操行分高,所以 1 1 1 先欣赏(第 1 1 1 个人等待了 2 2 2 个单位时间)。
1 1 1 欣赏完(时间 30 30 30)后,第 3 3 3 个人开始欣赏(一共等待了 10 10 10 个单位时间)。
3 3 3 欣赏完后一直到时间 100 100 100,第 5 5 5 个人到达(没有等待)。
第 5 5 5 个人欣赏的时候,第 2 2 2 个人到了,在 5 5 5 个单位时间后开始欣赏。
那么综上,等待最多的是第 3 3 3 个人,等待时间最多为 10 10 10。
一道比较水的题。
这道题的关键应该就是找每个人进去观赏的时间点。
先对所有人按照到达时间排序,第一个到的人肯定是最先观赏的,然后就把第一个人还没观赏完就到了的人丢进优先队列了(以操行分排的大根堆),下一个观赏的人就是在堆顶的那个人。按照这个模拟就可以了。
最后的时候, a n s = m a x { e n t e r i − a i } ans=max\{enter_i-a_i\} ans=max{enteri−ai}( e n t e r i enter_i enteri 记录的是进去观赏的时间点)。
#include
#include
#include
#include
#define N 100005
using namespace std;
int enter[N];
struct student{int start,t,id,Score;}a[N];
priority_queue<student>q;
bool operator<(const student &p,const student &q){return p.Score<q.Score;}
bool comp(const student &p,const student &q){return p.start<q.start;}
int main()
{
int n,i,sum=0;
scanf("%d",&n);
int tot=n;
for(i=1;i<=n;++i)
{
scanf("%d%d",&a[i].start,&a[i].t);
a[i].Score=tot--;
}
sort(a+1,a+n+1,comp);
for(i=1;i<=n;++i) a[i].id=i;
q.push(a[1]);
int last=2,lasttime=0;
while(sum<n)
{
if(!q.empty())
{
sum++;
student now=q.top();q.pop();
enter[now.id]=max(now.start,lasttime);
lasttime=enter[now.id]+now.t;
for(i=last;i<=n;++i)
{
if(a[i].start>lasttime)
{
last=i;
break;
}
q.push(a[i]);
}
}
else q.push(a[last++]);
}
int ans=0;
for(i=1;i<=n;++i)
ans=max(ans,enter[i]-a[i].start);
printf("%d",ans);
return 0;
}