1017 Queueing at Bank (25分)

注意是求平均等待时间,而不是周转时间(受本学期os影响+_+)

这题大有文章(其实是寒假在家做题效率太低QAQ)

\(k\)个窗口分别维护对应的最早空闲时间,只要窗口一空闲即可安排顾客。

可以采用小根堆来维护,保证小根堆里的元素始终只有\(k\)个,每次出队的窗口即为当前窗口的最早空闲时间。

对每个顾客:

  • 若当前出队的窗口空闲,将当前窗口的空闲时间更新为\(a[i].arrive\_time+a[i].serve\_time\)
  • 若当前出队的窗口非空闲,则需等待,将当前窗口的空闲时间更新为\(heap.top()+a[i].serve\_time\)

注意:

  • 银行营业时间是\(8:00:00\)\(17:00:00\)
  • 每个客户最多只能服务\(60min\)\(PAT\)数据貌似没体现这一点,\(AcWing\)数据是有体现的
  • 只要客户在\(17:00:00\)之前排上队,则即使办理业务时超过\(17:00:00\),也会被服务
const int N=10010;
struct Customer {
    int hh,mm,ss;
    int arrive_time;
    int serve_time;
    bool operator<(const Customer &W) const
    {
        return arrive_time<W.arrive_time;
    }
}a[N];
int n,m;

int main()
{
    cin>>n>>m;

    for(int i=0;i<n;i++)
    {
        scanf("%d:%d:%d %d",&a[i].hh,&a[i].mm,&a[i].ss,&a[i].serve_time);
        a[i].serve_time=min(a[i].serve_time,60);
        a[i].arrive_time=a[i].hh*3600+a[i].mm*60+a[i].ss;
    }

    sort(a,a+n);

    priority_queue<int,vector<int>,greater<int> > heap;

    for(int i=0;i<m;i++) heap.push(8*3600);

    int res=0,cnt=0;
    for(int i=0;i<n;i++)
    {
        int t=heap.top();
        heap.pop();

        if(a[i].arrive_time > 17*3600) break;

        if(a[i].arrive_time >= t)
            heap.push(a[i].arrive_time+a[i].serve_time*60);
        else
        {
            res+=t-a[i].arrive_time;
            heap.push(t+a[i].serve_time*60);
        }
        cnt++;
    }

    if(!cnt) puts("0.0");
    else printf("%.1f\n",res/60.0/cnt);
    //system("pause");
    return 0;
}
posted @ 2021-01-09 23:15  Dazzling!  阅读(65)  评论(0编辑  收藏  举报