1014. Waiting in Line (30)

题目链接:https://www.patest.cn/contests/pat-a-practise/1014


题目大意:银行有N个窗口,每个窗口前的黄线内最多排队M个人,有K个人要去办理业务,每个人要办理的时间已知。排队的规则跟现实生活中的排队类似,黄线内没有位置的时候,在线外候着;黄线内有位置的时候,选择队列最短的去排队,若有两个队长度相同,则选择队列序号小的排入。最后计算每个人办理完结束的时间。


解题思路:

  • 每个人用结构体表示,分量有要接受服务的时间serve;离开的时间leave,为便于计算,用分钟表示,最后再进行转换.

  • N个窗口,用N个队列来表示.

  • customer[i].leave=open[windowindex]+customer[i].serve.其中open[windowindex],windowindex表示该人所在窗口的序号;open[windowindex]为该人开始办理时的时间,该时间又等于上一个离开的时间,即当前人的open[windowindex]=customer[i-1].leave;下一个人的open[windowindex]=cusomer[i].leave

  • 确定每个人应该选择哪个窗口时有两种情况:
    1.黄线内的部分:每个人的窗口号为p%N
    2.黄线的外的人比较复杂。判断黄线外的人的窗口好的时候,选择所有队列中队头的人离开时间最早的那个队排入


代码如下:

#include <iostream>
#include <queue>
#include <cstdio>
#include <vector>
using namespace std;
struct person
{
  int serve,leave;//要接受服务的时间,离开的时间
};
int main(int argc, char const *argv[])
{
  int N,M,K,Q;
  cin>>N>>M>>K>>Q;
  person curstomers[K];//共k个人
  /*输入每个人接受服务的时间*/
  for(int i=0;i<K;i++)
    cin>>curstomers[i].serve;
  vector<queue<int>> window(N);//共N个窗口
  int open[N]={0};//每个窗空闲出来的时间初试化为0

  /**先把黄线内的人离开时间确定下来**/
  int p;//
  for(p=0;p<M*N&&p<K;p++){
    curstomers[p].leave=open[p%N]+curstomers[p].serve;//该顾客结束的时间为当前窗口空闲出的时间+需要服务的时间
    open[p%N]=curstomers[p].leave;//该空闲下来的时间为该顾客离开的时间
    window[p%N].push(p);//p放入该窗口的队列中
  }

  /*开始确定等在黄线外的人的离开时间*/
  while(p<K){
    /*每个人都每次从三个窗口的队头选一个离开时间最短的入队,
    也就是最短的队*/
    int minleave=curstomers[window[0].front()].leave;
    int minwin=0;
    for(int i=1;i<N;i++){
      if(minleave>curstomers[window[i].front()].leave){
        minwin=i;
        minleave=curstomers[window[i].front()].leave;
      }
    }
    /*找到队伍之后开始入队*/
    window[minwin].pop();//服务好的人出队
    window[minwin].push(p);
    curstomers[p].leave=open[minwin]+curstomers[p].serve;
    open[minwin]=curstomers[p].leave;
    p++;
  }

  /*开始查询*/
  int no;
  for(int i=0;i<Q;i++){
    cin>>no;
    if(curstomers[no-1].leave-curstomers[no-1].serve>=540)
      printf("Sorry\n");
    else
      printf("%02d:%02d\n",8+curstomers[no-1].leave/60,curstomers[no-1].leave%60);
  }
  return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值