Codeforces Yandex.Algorithm 2011 Round 1 B(模拟排队问题)

题意:n个人去银行办理手续,每个人到达银行的时间是ci,办理整个程序,需要3个步骤来完成,不同步骤有不同的窗口,同一个步骤有若干个窗口。一个人办理手续,必须按照步骤顺序办理,即先去办理步骤1,办理完再去办理步骤2,办理完再去办理步骤3,然后全部办理完。嗯。

每个步骤有ki个窗口,每个步骤的窗口办理一个人的时间是ti(跟人无关,只跟步骤有关),每个步骤的窗口办理效率是一样的。嗯

现在问,n个人里,需要在银行呆的时间最久是多久。。一个人在银行呆的时间算为:他到达的时间 到 他办理完步骤3的时间。。嗯。。其他过程视为瞬时间完成的,比如从等待区到窗口等。

链接:http://codeforces.com/contest/85/problem/B

解法:很显然就是一道模拟题,一个人到达了,那么就让它去步骤一的一个窗口去办理,如果没人了,就让他等待,办理完一,就让它去步骤二的一个窗口办理,如果没人了,就让他等待。。这样做,,只要有窗口,就让一个人马上去。。可是怎么实现呢???

我用了4个优先队列,优先队列里存储时间,此人的编号,此人的类型。。第0个有限队列存储还没有到达以及正在窗口办理的人,第i(i = 1, 2, 3)个优先队列存储准备去步骤 i 办理但在等待的人。。具体我描述不清楚。。

但有一个方法挺重要的,,不妨想像一个时间轴,,那么在同一个时刻发生的事情就让它一起发生,一起处理,,然后从这个时刻跳到下一个时刻过程中,去更新4个优先队列什么的。。就这样子做。。

具体看代码吧。。

代码

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstdlib>
#include<cstring>
#include<stack>
#include<queue>
using namespace std;
typedef long long ll;

#define N 100010
ll k[10];
ll t[10];
int n;
ll c[N], uset[N];

struct Data{
    ll t;
    int ty, id;
    Data(){};
    Data(ll t1, int ty1, int id1){
        t = t1, ty = ty1, id = id1;
    }
    friend bool operator < (const Data a, const Data b){
        return a.t > b.t;
    }
};
priority_queue<Data>q[4];

ll solve(){
    ll nowt = 0;
    for(int i = 1; i <= n; i++){
        Data d = Data(c[i], 0, i);
        q[0].push(d);
    }

    while(q[0].empty() == 0){
        nowt = q[0].top().t;
        while(q[0].empty() == 0){
            Data d = q[0].top();
            if(d.t != nowt) break;
            q[0].pop();
            uset[d.id] += t[d.ty];
            k[d.ty] += 1;
            if(d.ty != 3){
                d.ty += 1;
                d.t = nowt;
                q[d.ty].push(d);
            }
        }
        for(int i = 3; i >= 1; i--){
            while(k[i] > 0 && q[i].empty() == 0){
                Data d = q[i].top();
                q[i].pop();
                uset[d.id] += nowt - d.t;
                k[d.ty] -= 1;
                d.t = nowt + t[d.ty];
                q[0].push(d);
            }
        }
    }

    ll ans = 0;
    for(int i = 1; i <= n; i++){
        ans = max(ans, uset[i]);
    }

    return ans;
}

int main(){
    for(int i = 1; i <= 3; i++) cin >> k[i];
    for(int i = 1; i <= 3; i++) cin >> t[i];
    cin >> n;
    for(int i = 1; i <= n; i++) cin >> c[i];

    cout << solve() << endl;

    return 0;
}

你可能感兴趣的:(模拟)