题解:ABC320E - Somen Nagashi

题解:ABC320E - Somen Nagashi

·题目

链接:Atcoder。

链接:洛谷。

·难度

算法难度:B。

思维难度:B。

调码难度:A。

综合评价:普及+/提高。

·算法

堆/set。

·思路

我们需要实现以下功能(该容器可以手写堆实现,也可以用set):支持快速插入删除,并能够随时取出所有元素中的最小值。我们用其中一个存储吃完面条回来的人的编号、时间的组合(结构体Info),另一个存储现在队列中存在的人的编号。每次操作将所有时间小于t的“吃完面条回来的人”入队,并将该任务删除,之后将w的面条加到队列中编号最小的人身上,并添加回归任务“这个人在s+t的时间出完面条归队”,然后在队列中删除这个人。最后输出每个人的面条数目即可。

·代价

O(n+m*log(n)),因为set、堆等都有log级别的代价。

·细节

迭代器用法和指针基本相同。

·代码

#include
#define N 220000
using namespace std;
struct Info{
    long long node,ttime;
    bool operator<(Info ot)const{
        if(ttime==ot.ttime){
            return noded={};
//回归任务
setzd={};
//队列信息
long long sum[N]={},m=0,n=0;
//sum就是面条数目
int main(){
    scanf("%lld%lld",&n,&m);
    for(long long i=1;i<=n;i++){
        zd.insert(i);
    }
    //输入,并记录每个人都在队列中
    for(long long i=1;i<=m;i++){
        long long s=0,t=0,w=0;
        scanf("%lld%lld%lld",&t,&w,&s);
        while(d.empty()==false&&d.begin()->ttime<=t){
            zd.insert(d.begin()->node);
            d.erase(d.begin());
        }
        //完成需要完成的回归任务
        if(zd.empty()==false){
            sum[*zd.begin()]+=w;
            d.insert({*zd.begin(),t+s});
            zd.erase(zd.begin());
        }
        //如果可以,就让队首的人得到面条离开一段时间
    }
    for(long long i=1;i<=n;i++){
        printf("%lld\n",sum[i]);
    }
    //输出答案
    return 0;
}

·注意

手写堆很长,不推荐。

你可能感兴趣的:(c++,set)