排队“夹塞”是引起大家强烈不满的行为,但是这种现象时常存在。在银行的单窗口排队问题中,假设银行只有1个窗口提供服务,所有顾客按到达时间排成一条长龙。当窗口空闲时,下一位顾客即去该窗口处理事务。此时如果已知第i位顾客与排在后面的第j位顾客是好朋友,并且愿意替朋友办理事务的话,那么第i位顾客的事务处理时间就是自己的事务加朋友的事务所耗时间的总和。在这种情况下,顾客的等待时间就可能被影响。假设所有人到达银行时,若没有空窗口,都会请求排在最前面的朋友帮忙(包括正在窗口接受服务的朋友);当有不止一位朋友请求某位顾客帮忙时,该顾客会根据自己朋友请求的顺序来依次处理事务。试编写程序模拟这种现象,并计算顾客的平均等待时间。

输入格式:

输入的第一行是两个整数:1,为顾客总数;0,为彼此不相交的朋友圈子个数。若M非0,则此后M行,每行先给出正整数2,代表该圈子里朋友的总数,随后给出该朋友圈里的L位朋友的名字。名字由3个大写英文字母组成,名字间用1个空格分隔。最后N行给出N位顾客的姓名、到达时间T和事务处理时间P(以分钟为单位),之间用1个空格分隔。简单起见,这里假设顾客信息是按照到达时间先后顺序给出的(有并列时间的按照给出顺序排队),并且假设每个事务最多占用窗口服务60分钟(如果超过则按60分钟计算)。

输出格式:

按顾客接受服务的顺序输出顾客名字,每个名字占1行。最后一行输出所有顾客的平均等待时间,保留到小数点后1位。

输入样例:

6 2
3 ANN BOB JOE
2 JIM ZOE
JIM 0 20
BOB 0 15
ANN 0 30
AMY 0 2
ZOE 1 61
JOE 3 10

输出样例:

JIM
ZOE
BOB
ANN
JOE
AMY
75.2
解析 : 为窗口设置时间, 然后把数组扫一遍, 如果person.arivetime < win.time && win.id = person.id, 那么这个person 便可处理,并更新win.time。
#include <bits/stdc++.h>
using namespace std;
typedef struct Person
{
    int id, atime, ntime, wtime;
    char name[5];
}Person;
typedef struct Window
{
    int time;
    int id;
}Window;
bool cmp(Person p1, Person p2)
{
    return p1.id < p2.id;
}
Person per[10010];
Window win;
int M, N;
int main()
{
    int num, total = 0, ranking = 1;
    char name[5];
    map<string, int>mp;
    scanf("%d %d", &N, &M);
    for(int i =1; i <= M; ++i)
    {
        scanf("%d", &num);
        for(int j = 1; j <= num; ++j)
        {
            scanf("%s", name);
            mp[name] = i;
        }
    }
    for(int i = 1; i <= N; ++i)
    {
        scanf("%s %d %d", per[i].name, &per[i].atime, &per[i].ntime);
        if(per[i].ntime > 60)
            per[i].ntime = 60;
        per[i].id = mp[per[i].name];
    }
    int  cur = 2;
    win.time = per[1].atime + per[1].ntime;
    win.id = per[1].id;
    per[1].id = ranking++;
    for(int i = 2; i <= N; ++i)
    {
        if(per[i].ntime != 0)
        {
          cur = i;
          while(win.time >= per[cur].atime && cur <= N)
          {
              if(win.id ==  per[cur].id && win.id != 0 && per[cur].ntime != 0)
              {
                  per[cur].wtime = win.time - per[cur].atime ;
                  total += per[cur].wtime;
                  win.time  = per[cur].atime + per[cur].ntime + per[cur].wtime;
                  per[cur].ntime = 0;
                  per[cur].id = ranking++;
              }
              cur++;
          }
          if(per[i].ntime != 0)
          {
              if(win.time < per[i].atime)
              {
                  per[i].wtime = 0;
              }
              else
              {
                  per[i].wtime = win.time - per[i].atime;
              }
              total += per[i].wtime;
              win.time = per[i].atime + per[i].ntime + per[i].wtime;
              win.id = per[i].id;
              per[i].ntime = 0;
              per[i].id = ranking++;
          }
        }
    }
    sort(per + 1, per + N + 1, cmp);
    for(int i = 1; i <= N; ++i)
      printf("%s\n", per[i].name);
    printf("%.1lf\n", (total * 1.0) / (N * 1.0));
}