C - Coffee Break

传送门

题意:

Monocarp有一份工作,一天工作m分钟。他想喝咖啡,这里有n个喝咖啡的时间点,a[1],a[2]....a[n] , 注意 a[i]<=m。老板有规定,喝咖啡的间隔点不能少于d分钟。问至少需要多少天,Monocarp才能喝完这n个时间点的咖啡。

思路:

先将咖啡时间点从小到大排序,我们依次进行分配。如果当前已经喝了t天,我们要判断a[i]是可以在这t天中有一天喝掉?还是需要在t+1天中喝掉。我们只需要把这t天中的每一天喝的最近的一个咖啡时间点放进优先队列中。每一次将当前a[i]点和队首元素(喝咖啡最小时间点)比较即可。

代码:

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <queue>
const int maxn=2e5+10;
using namespace std;
struct node {
    int val,indx,ans;
    friend bool operator < (node a,node b){  //规定优先队列的排列顺序(小->大)
        return a.val>b.val;
    }
};  //定义结构体
int n,m,d;
node a[maxn];
priority_queue<node>q;
bool cmp(node a,node b){
    return a.indx<b.indx;
}
bool cmp1(node a,node b){
    return a.val<b.val;
}
int main(){
    cin>>n>>m>>d;
    for (int i=1; i<=n; i++) {  //输入
        int x;cin>>x;
        a[i].val=x;
        a[i].indx=i;          //indx 为当前点的位置--为输出做准备
    }
    sort(a+1, a+1+n, cmp1);    //以时间val从小到大排序--依次入队列。
    a[1].ans=1;q.push(a[1]);   //首先将最小的入队列,第一天的第一杯咖啡
    int t=1;                 //t 为喝咖啡的天数
    for (int i=2; i<=n; i++) {  //遍历2-n个咖啡点
        if (a[i].val>q.top().val+d) { //如果当前咖啡时间和队首(最小的)咖啡时间相差大于d
            a[i].ans=q.top().ans;    //说明这一杯咖啡可以在队首元素这一天喝掉
            q.pop();               //队首出队列,当前a[i]会取而代之
        }
        else a[i].ans=++t;          // 如果<=d,说明当前咖啡时间不能在队列中任一天数喝,就需要新一天来喝
        q.push(a[i]);              //更新这一天喝的刚喝的咖啡,方便下一次比较
    }
    sort(a+1, a+1+n, cmp); //以位置从小到大排序--符合输出要求。
    cout<<t<<endl;
    for (int i=1; i<=n; i++) cout<<a[i].ans<<' ';
    cout<<endl;
}

 

posted @ 2020-06-05 21:15  驿书达  阅读(156)  评论(0编辑  收藏  举报