#include <stdio.h>
#include <string.h>
#define maxsize 100001
struct friends
{
char fri[maxsize][4];
}circle[101]; // 朋友圈
struct QueueData
{
char name[4];
int time;
int pime;
}queue[maxsize];
int s[maxsize];//判断顾客是否已经处理过,以处理用1表示
int len[101]; // 第几个圈子内有几个朋友
int main()
{
int n, m;
scanf("%d %d", &n, &m);
//若圈子不为0, m为圈子数
if(m)
{
for(int i=0; i<m; i++)
{
int l;
scanf("%d", &l);
len[i] = l;
for(int j=0; j<l; j++)
{ //输入圈子中的名字
scanf("%s", circle[i].fri[j]);
}
}
}
//输入所有顾客信息
for(int i=0; i<n; i++)
{
scanf("%s %d %d", queue[i].name, &queue[i].time, &queue[i].pime);
if(queue[i].pime > 60) queue[i].pime = 60;
}
// 计算
int sum_time = 0; //总共等待时间
int win_time = 0; //窗口完成时间
for(int i=0; i<n; i++)
{
if(s[i] == 0) //不是圈子里的且没有被处理的顾客,圈子里的第一个
{
if(queue[i].time >= win_time)//不需要等待
{
win_time += (queue[i].time - win_time) + queue[i].pime;
}
else //需要等待
{
sum_time += win_time - queue[i].time;
win_time += queue[i].pime;
}
printf("%s\n", queue[i].name);
int flag = 0;//是否有圈子
int index = 0; //顾客所在的圈子位置
// 先判断queue[i]顾客所属哪个圈子,再夹塞
for(int j=0; j<m; j++)
{
for(int k=0; k<len[j]; k++)
{
if(strcmp(queue[i].name, circle[j].fri[k]) == 0)
{
flag = 1;
index = j;//把哪号圈子记住
break;
}
}
}
// 属于圈子, 判断后面的顾客有没有跟他是同圈子的
if(flag)
{
for(int j=i+1; j<n; j++)
{
for(int k=0; k<len[index]; k++)
{
if(strcmp(queue[j].name, circle[index].fri[k])==0 && s[j]==0)//在圈子里找,自前向后
{
if(queue[j].time > win_time) break; //夹塞顾客未在窗口完成时间内赶到
// 提前或者准时到达,进行夹塞操作
sum_time += win_time - queue[j].time;
win_time += queue[j].pime;
s[j] = 1;
printf("%s\n", queue[j].name);//输出夹塞顾客
}
}
}
}
}
s[i] = 1;
}
// 输出平均等待时间 小数点后一位
printf("%.1f", 1.0*sum_time/n);
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
//朋友圈 人名映射到朋友圈
typedef struct LNode
{
int name;
int arrive;
int deal;
}LNode;
int circle[20000]={0};
int Hash(char *str)//哈希映射
{
return (str[0]-65)*26*26+(str[1]-65)*26+(str[2]-65);
}
void print_name(int s)
{
printf("%c%c%c\n",s/26/26+65,s/26%26+65,s%26+65);//与上面关系对应
}
int main()
{
int n,m,i;
scanf("%d %d",&n,&m);
LNode *p=(LNode*)malloc(sizeof(LNode)*n);//结构体数组
int head=0,tail=0;
int *book=(int*)malloc(sizeof(int)*n);//一维数组
for(i=0;i<n;i++) book[i]=0;//初始化
for(i=1;i<=m;i++)
{
//m个圈子,每个圈子里有num人
int num;
scanf("%d",&num);
while(num--)
{
char s[4];
scanf("%s",s);
circle[Hash(s)]=i+1;//归属哪一个圈子 从2号圈子开始,圈子互不相交,散列冲突情况概率极小;相同圈子数组值大小一样
}
}
for(i=0;i<n;i++)
{
char s[4];
scanf("%s %d %d",s,&p[i].arrive,&p[i].deal);
if(p[i].deal>60) p[i].deal=60;
p[i].name=Hash(s);
}
int coun=0;
book[0]=1;//应该是标记办过业务了
print_name(p[0].name);
int left,sum=0;
left=p[0].arrive+p[0].deal;//应当离开的时间
coun++;//计数器
LNode front=p[0];
while(coun<=n){
//寻找下一个需要办理的人
//printf("%d\n",sum);
int flag=0;
for( i=0;i<n;i++)
{
if(book[i]) continue;
if(p[i].arrive>left) break;//来晚了
if(circle[front.name]==circle[p[i].name]&&p[i].arrive<=left)//一个圈子里的并且在他离开前到达
{
//printf("I find a friend and I can help him!\n");
flag=1;
book[i]=1;//标记处理过
print_name(p[i].name);//打印;
sum+=left-p[i].arrive;
left+=p[i].deal;//帮朋友处理,离开时间变长
front=p[i];//下一个为子队列的头
break;
}
}
if(!flag){//按顺序进行查找,不插队
for(i=0;i<n;i++)
{
if(book[i]) continue;
//printf("I can not a friend,so I must find next one\n");
print_name(p[i].name);
book[i]=1;
if(left<=p[i].arrive) sum+=0;
else sum+=left-p[i].arrive;
if(p[i].arrive>=left) left=p[i].arrive;
left+=p[i].deal;
front=p[i];
break;
}
}
coun++;
}
printf("%.1lf\n",(sum*1.0)/n);
}