1026. Table Tennis

本文介绍了一种窗口排队问题的算法实现,通过用户到达时间和窗口服务时间的管理来解决排队问题。文章提供了完整的C++代码示例,并解释了如何处理VIP客户优先服务的情况。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#include<iostream>
#include<cstdio>
#include<vector>
#include<algorithm>
using namespace std;
const int INF=1<<30,K=103;
struct node{
  int come,cost,vip,serve,done;
  node(int a,int b,int c,int d,bool e):come(a*3600+b*60+c),
      cost(min(d*60,7200)),vip(e),done(false),serve(INF){}
};
typedef const node& cnr;
vector<node>man;
vector<int>fre;
int n,k,m,cnt[K],vip[K];

void prtime(int k){
  printf("%02d:%02d:%02d ",k/3600,(k%3600)/60,k%3600%60);}
void play(node&he,int nth){
  int began=max(he.come,fre[nth]);
  he.done=true; ++cnt[nth]; he.serve=began;
  fre[nth]=began+he.cost;
}
int main(){
  scanf("%d",&n); man.reserve(10006);
  for(int i=0,a,b,c,d,e;i<n;++i){
    scanf("%d:%d:%d%d%d",&a,&b,&c,&d,&e);
    man.emplace_back(a,b,c,d,e); }
  sort(man.begin(),man.end(),[](cnr x,cnr y){return x.come<y.come;});
  scanf("%d%d",&k,&m);  fre.assign(k,8*3600);
  for(int i=0,no;i<m;++i){ scanf("%d",&no); vip[no-1]=true; }

  for(int cur=0;cur<man.size();++cur){
    auto &he=man[cur];  if(he.done)continue;
    int line=max(he.come,*min_element(fre.begin(),fre.end())); if(line>=21*3600)break;
    int vipt=-1,vipu=-1,vopt=-1;
    for(int i=0;i<k;++i) if(fre[i]<=line){
  	if(vopt==-1) vopt=i;
  	if(vip[i]&&vipt==-1)vipt=i;
    }
    for(int i=cur;i<n&&man[i].come<=line;++i)
      if(man[i].vip&&vipu==-1&&!man[i].done) vipu=i; 
    if(vipu!=-1 &&vipt!=-1){ play(man[vipu],vipt);--cur; }
    else play(he,vopt);
  }//for(int cur...
  sort(man.begin(),man.end(),[](cnr x,cnr y){return x.serve<y.serve;});
  for(auto &x:man) if(x.serve!=INF){
      prtime(x.come); prtime(x.serve); cout<<(x.serve-x.come+30)/60<<endl;}
  for(int i=0;i<k;++i) cout<<(i?" ":"")<<cnt[i];
}

窗口排队的题首先都按用户到达时间排序,如果不插队的话,每个窗口记录自己的时间,只要不断用队头用户刷新窗口的记录时间即可。每次轮到队头用户时,可能有一些窗口空闲,可以选空闲窗口编号最小的,也可以选空闲窗口中释放时间最早的,都不影响结果;也可能没有窗口空闲,此时只能选释放时间最早的,因此一般题目不断用队头用户刷新释放时间最早的窗口的时间记录即可。例如advance level的1014 waiting in line 和1017 queueing at bank和数据结构题集里的8-05. 银行排队问题之“多队列多窗口”版 。   

这个题如果分情况讨论的话很麻烦。分配一张桌子呢肯定是既有等待的用户又有空闲的桌子的时候,即max( 队头到达时间,min( 各窗口释放时间 ) ),以此时间为分界只有一种情况需要插队,即既有等待的vip用户又有空闲的vip桌子,让vip与vip先配对即可。否则让最先来的队头用户与最先释放的桌子配对即可。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值