PAT A1017 Queueing at Bank [硬核模拟]

题目描述

链接
有n个客户,k个窗口。已知每个客户的到达时间和需要的时长,如果有窗口就依次过去,如果没有窗口就在黄线外等候(黄线外只有一个队伍,先来先服务),求客户的平均等待时长。银行开放时间为8点到17点,再8点之前不开门,8点之前来的人都要等待,在17点后来的人不被服务。

分析

  • 仔细模拟题意啊!!!!分情况讨论!!!见代码
  • 写代码开数组空间的时候!!一定慎重!!!!!!!!因为这个WA无数次了

代码

#include<bits/stdc++.h>
using namespace std;

int n,k;
const int maxn = 1e4+10;
struct window{
    int ed;
}wins[maxn];

struct node{
    int enter;
    int st;
    int cost;
    int ed;
}nodes[maxn];

int cal(int h,int m,int s){
    return h*3600 + m*60 + s;
}

bool cmp(node x, node y){
    return x.enter < y.enter;
}

int hh,mm,ss,cost;

int main(){
    scanf("%d%d",&n,&k);
    int len = 0;
    for(int i=0;i<n;i++){
        scanf("%d:%d:%d %d",&hh,&mm,&ss,&cost);
        if(hh > 17 || hh == 17 && mm > 0 || hh==17 && mm == 0 && ss > 0){
            continue;
        }
        nodes[len++] = {cal(hh,mm,ss), 0, cost*60, 0};
    }
    sort(nodes,nodes+len,cmp);
    int wait = 0;
    for(int i=0;i<len;i++){
        int min = 0;
        for(int j=0;j<k;j++){  //找出最近的结束使用时间
            if(wins[min].ed > wins[j].ed) min = j;
        }
        if(wins[min].ed <=  nodes[i].enter){ //如果进来的时候窗口已经是可用了
            if(nodes[i].enter < 8*3600){ //特殊情况是进来时还没开窗口
                wait += 8*3600 - nodes[i].enter;
                nodes[i].st = 8*3600;
                nodes[i].ed = nodes[i].st + nodes[i].cost;
                wins[min].ed = nodes[i].ed;
            }else{ //立马就用
                wait += 0;
                nodes[i].st = nodes[i].enter;
                nodes[i].ed = nodes[i].st + nodes[i].cost;
                wins[min].ed = nodes[i].ed;
            }
        }else{ //进来时窗口还在忙,必须等待
            wait += wins[min].ed - nodes[i].enter;
            nodes[i].st = wins[min].ed;
            nodes[i].ed = nodes[i].st + nodes[i].cost;
            wins[min].ed = nodes[i].ed;
        }
    }
    printf("%.1f\n", wait*1.0/60/len);

}

猜你喜欢

转载自www.cnblogs.com/doragd/p/11386528.html