其实是个模拟题。。
/* 每个人都有一个口渴时间,如果口渴时,其前面没有人在排队,那么其就去排队接水,反之一直等到前面没有人排队 问每个人接完水的时间 每个没轮到的人都在位置上等前面的人接完水,然后他再去排队 先把每个人按照口渴时间排序 设新加入队列的人是now,那么口渴时间在 now.s->now.t 之间的所有人都会进入等待状态 在now前面的人会直接去排队,在now后面的人会继续等待 当这条队列都排完后,那些等待状态中的,最靠前的人会去排队 依次类推,用队列维护排队的人,用优先队列维护等待的人 */ #include<bits/stdc++.h> #include<queue> using namespace std; #define N 100005 #define ll long long #define INF 0x3f3f3f3f3f3f3f3f ll n,ans[N],P; struct Node{ ll s,id; bool operator<(Node b)const { return id>b.id; } }p[N]; int cmp(Node a,Node b){ if(a.s==b.s)return a.id<b.id; return a.s<b.s; } int main(){ cin>>n>>P; for(int i=1;i<=n;i++){ cin>>p[i].s; p[i].id=i; } sort(p+1,p+1+n,cmp); queue<Node>q; priority_queue<Node>pq; int index=1,finish=0; pq.push(p[1]); ll time=p[1].s; while(1){ Node cur; if(pq.size()){ cur=pq.top(); pq.pop(); } else { cur=p[++index]; time=p[index].s;//时间直接跳过去 } q.push(cur); while(index+1<=n){ Node tmp=q.back(); if(p[index+1].s<=time+1ll*q.size()*P){ //放到pq里 if(p[index+1].id>tmp.id) pq.push(p[++index]); //放到q里 else q.push(p[++index]); } else break; } //q队列的的都可以出队了 while(q.size()){ Node tmp=q.front();q.pop(); time+=P; ans[tmp.id]=time; finish++; } if(finish==n)break; } for(int i=1;i<=n;i++) cout<<ans[i]<<' '; }