题目描述
链接
k张桌子,球员到达后总是选择编号最小的桌子。如果训练时间超过2h会被压缩成2h,如果到达时候没有球桌空闲就变成队列等待。
k张桌子中m张是vip桌,如果vip桌子有空闲,而且队列里面有vip成员,那么等待队列中的第一个vip球员会到最小的vip球桌训练。如果vip桌子空闲但是没有vip来,那么就分配给普通的人。如果没有vip球桌空闲,那么vip球员就当作普通人处理。
给出每个球员的到达时间、要玩多久、是不是vip(是为1不是为0)。给出球桌数和所有vip球桌的编号,QQ所有在关门前得到训练的球员的到达时间、训练开始时间、等待时长(取整数,四舍五入),营业时间为8点到21点。如果再21点后还没有开始玩的人,就不再玩,不需要输出~
分析
建立两个结构体,person 和 tablenode,分别创建他们的结构体数组player和table。
因为给出的输入是无序的所以要先排序。可以根据最早空闲的桌子是不是vip桌进行分类讨论。
如果最早空闲的桌子index是vip桌,那么寻找队列里面第一个vip球员。根据他的到达时间继续分类讨论。
如果最早空闲的桌子index不是vip桌,那么看队首的球员是不是vip球员。如果是普通人,就直接把球桌分配给他,如果是vip,那么需要找到最早空闲的vip桌子的号vipindex,根据vip球员的到达时间和vipindex桌子的空闲时间继续分类讨论。
分配的时候标记table的num++,统计该table服务的人数。
- 当然我不是这样做的
我的代码
#include<bits/stdc++.h> using namespace std; const int maxn = 10000 + 10; struct node{ int enter; int st; int cost; int ed; int tag; int use; }nodes[maxn]; struct table{ int tag; int ed; int cnt; }tables[maxn]; int cal(int h,int m,int s){ return h*3600 + m*60 + s; } void trans(int sum, int &h, int &m, int &s){ h = sum / 3600; m = sum % 3600 / 60; s = sum % 60; } bool cmp(node x, node y){ return x.enter < y.enter; } int hh,mm,ss,p,tag,k,m,n; int main(){ scanf("%d",&n); for(int i=0;i<n;i++){ scanf("%d:%d:%d %d %d",&hh,&mm,&ss,&p,&tag); nodes[i].enter = cal(hh,mm,ss); nodes[i].cost = p*60; nodes[i].tag = tag; } scanf("%d%d",&k,&m); for(int i=0;i<m;i++){ int tmp; scanf("%d",&tmp); tables[tmp-1].tag = 1; } sort(nodes,nodes+n,cmp); for(int i=0;i<n;i++){ if(nodes[i].use == 1) continue; int min = 0; for(int j=0;j<k;j++){ if(tables[min].ed > tables[j].ed){ min = j; } } if(tables[min].ed <= nodes[i].enter){ //进来时,已经有桌子可用 nodes[i].use = 1; int h,m,s; trans(nodes[i].enter, h, m, s); printf("%02d:%02d:%02d ",h,m,s); nodes[i].st = nodes[i].enter; printf("%02d:%02d:%02d 0\n",h,m,s); tables[min].ed = nodes[i].st + nodes[i].cost; tables[min].cnt++; }else{ //需要等待 if(tables[min].ed >= 21*3600) continue; if(tables[min].tag == 0){ //普通桌子,按序分配 nodes[i].use = 1; int h,m,s; trans(nodes[i].enter, h, m, s); printf("%02d:%02d:%02d ",h,m,s); nodes[i].st = tables[min].ed; trans(nodes[i].st, h, m, s); printf("%02d:%02d:%02d %d\n",h,m,s, (int)round((nodes[i].st-nodes[i].enter)/60.0)); tables[min].ed = nodes[i].st + nodes[i].cost; tables[min].cnt++; }else{ int flag = 0; //标记是否有VIP用户在队列里 for(int q=i; q<n && nodes[q].enter < tables[min].ed; q++){ if(nodes[q].tag == 1 && nodes[q].use == 0){ //执行分配 nodes[q].use = 1; int h,m,s; trans(nodes[q].enter, h, m, s); printf("%02d:%02d:%02d ",h,m,s); nodes[q].st = tables[min].ed; trans(nodes[q].st, h, m, s); printf("%02d:%02d:%02d %d\n",h,m,s, (int)round((nodes[q].st-nodes[q].enter)/60.0)); tables[min].ed = nodes[q].st + nodes[q].cost; tables[min].cnt++; flag = 1; break; } } if(flag){ i--; }else{ //没有的话 nodes[i].use = 1; int h,m,s; trans(nodes[i].enter, h, m, s); printf("%02d:%02d:%02d ",h,m,s); nodes[i].st = tables[min].ed; trans(nodes[i].st, h, m, s); printf("%02d:%02d:%02d %d\n",h,m,s, (int)round((nodes[i].st-nodes[i].enter)/60.0)); tables[min].ed = nodes[i].st + nodes[i].cost; tables[min].cnt++; } } } } for(int i=0;i<k;i++){ if(i!=0) printf(" "); printf("%d",tables[i].cnt); } printf("\n"); }
别人的代码
#include <iostream> #include <vector> #include <algorithm> #include <cmath> using namespace std; struct person { int arrive, start, time; bool vip; }tempperson; struct tablenode { int end = 8 * 3600, num; bool vip; }; bool cmp1(person a, person b) { return a.arrive < b.arrive; } bool cmp2(person a, person b) { return a.start < b.start; } vector<person> player; vector<tablenode> table; void alloctable(int personid, int tableid) { if(player[personid].arrive <= table[tableid].end) player[personid].start = table[tableid].end; else player[personid].start = player[personid].arrive; table[tableid].end = player[personid].start + player[personid].time; table[tableid].num++; } int findnextvip(int vipid) { vipid++; while(vipid < player.size() && player[vipid].vip == false) vipid++; return vipid; } int main() { int n, k, m, viptable; scanf("%d", &n); for(int i = 0; i < n; i++) { int h, m, s, temptime, flag; scanf("%d:%d:%d %d %d", &h, &m, &s, &temptime, &flag); tempperson.arrive = h * 3600 + m * 60 + s; tempperson.start = 21 * 3600; if(tempperson.arrive >= 21 * 3600) continue; tempperson.time = temptime <= 120 ? temptime * 60 : 7200; tempperson.vip = ((flag == 1) ? true : false); player.push_back(tempperson); } scanf("%d%d", &k, &m); table.resize(k + 1); for(int i = 0; i < m; i++) { scanf("%d", &viptable); table[viptable].vip = true; } sort(player.begin(), player.end(), cmp1); int i = 0, vipid = -1; vipid = findnextvip(vipid); while(i < player.size()) { int index = -1, minendtime = 999999999; for(int j = 1; j <= k; j++) { if(table[j].end < minendtime) { minendtime = table[j].end; index = j; } } if(table[index].end >= 21 * 3600) break; if(player[i].vip == true && i < vipid) { i++; continue; } if(table[index].vip == true) { if(player[i].vip == true) { alloctable(i, index); if(vipid == i) vipid = findnextvip(vipid); i++; } else { if(vipid < player.size() && player[vipid].arrive <= table[index].end) { alloctable(vipid, index); vipid = findnextvip(vipid); } else { alloctable(i, index); i++; } } } else { if(player[i].vip == false) { alloctable(i, index); i++; } else { int vipindex = -1, minvipendtime = 999999999; for(int j = 1; j <= k; j++) { if(table[j].vip == true && table[j].end < minvipendtime) { minvipendtime = table[j].end; vipindex = j; } } if(vipindex != -1 && player[i].arrive >= table[vipindex].end) { alloctable(i, vipindex); if(vipid == i) vipid = findnextvip(vipid); i++; } else { alloctable(i, index); if(vipid == i) vipid = findnextvip(vipid); i++; } } } } sort(player.begin(), player.end(), cmp2); for(i = 0; i < player.size() && player[i].start < 21 * 3600; i++) { printf("%02d:%02d:%02d ", player[i].arrive / 3600, player[i].arrive % 3600 / 60, player[i].arrive % 60); printf("%02d:%02d:%02d ", player[i].start / 3600, player[i].start % 3600 / 60, player[i].start % 60); printf("%.0f\n", round((player[i].start - player[i].arrive) / 60.0)); } for(int i = 1; i <= k; i++) { if(i != 1) printf(" "); printf("%d", table[i].num); } return 0; }