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

输入格式:

输入的第一行是两个整数:1≤N≤10000,为顾客总数;0≤M≤100,为彼此不相交的朋友圈子个数。若M非0,则此后M行,每行先给出正整数2≤L≤100,代表该圈子里朋友的总数,随后给出该朋友圈里的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

题解:思路在注释里,就不在这里写了。

#include <bits/stdc++.h>    //双向链表实现,本题还有一个更好的优化方法,可以通过记录朋友属性的次数来忽略不必要的搜索
using namespace std;
typedef struct consumer
{char name[5];double arrive;double start;double process;double end;double wait;struct consumer *next; //朋友找人帮忙看的是end,输出看的是start. struct consumer *prior;
}List;
int main()
{int n,m;char name[5];int record[60][60][60]={0};  //这个数组每一个下标代表着名字的每一个字母,数组元素存放着共同属性---是不是朋友,一种更为简单的方法是使用map函数List *head=NULL,*tail,*p;    //本机调试不减65很容易段错误,可能是三维数组的特性?cin>>n>>m;for (int i=1;i<=m;i++)   //输入朋友圈 {int k;cin>>k;for (int j=0;j<k;j++){getchar();scanf("%s",name);record[name[0]-65][name[1]-65][name[2]-65]=i;}}double arrive,process,lastendtime=0;for (int i=0;i<n;i++)   //每个人的信息并在输入的过程中查看前面有没有朋友 {                       //有没有朋友指自己的到达时间比朋友离开的时间要早,即下面的判断条件 int flag=0;         //record[temp->name[0]-65][temp->name[1]-65][temp->name[2]-65]==record[p->name[0]-65][p->name[1]-65][p->name[2]-65]&&p->arrive<=temp->endscanf("%s%lf%lf",name,&arrive,&process);if (process>60) process=60;p=(List *)malloc(sizeof(List));   //为朋友节点赋值 p->next=NULL;p->prior=NULL;strcpy(p->name,name);p->arrive=arrive;p->process=process;if (i==0)                        //第一个人一定是一来就被处理 {p->start=p->arrive;}else                            //lastendtime是窗口的availiable的时间 {if (p->arrive<=lastendtime)    //到的时间比availiable时间早,那么需要等一会,一有空就去处理 p->start=lastendtime;else                          //这是窗口有一段空的时间,来了就处理,同时要注意下边56行对lastendtime的刷新 p->start=p->arrive;}p->end=p->start+p->process;       //结束时间 lastendtime=p->end;              //刷新 p->wait=p->start-p->arrive;        //计算此人的等待时间 if (p->wait<0)   p->wait=0;        //如果等待时间为负,那么说明来的比lastendtime晚,没等待(注:实际上,53行已考虑了) if (head==NULL)       //插入 {head=p;tail=p;            //别忘了,不然后面的插入会发生段错误 }else{for (List *temp=tail;temp!=NULL;temp=temp->prior)   //找朋友 {if (record[temp->name[0]-65][temp->name[1]-65][temp->name[2]-65]==record[p->name[0]-65][p->name[1]-65][p->name[2]-65]&&p->arrive<=temp->end)   //temp处是要插入的前一个位置 {   //如果二人属性相同并且后来者是赶在朋友走之前来的 flag=1;  //需要在前面插入 for (List *rr=temp->next;rr!=NULL;rr=rr->next)   //temp是他的朋友,在这个人加塞后,后面的每个人都要 {                                          //加时长 rr->start+=p->process;rr->end+=p->process;rr->wait=rr->start-rr->arrive;if (rr->wait<=0) rr->wait=0;}if (temp->next==NULL)    //样例中BOB和ANN的情况,如果朋友也在最后,那么tail要移动到这个人 {tail=p;}p->start=temp->end;           //朋友的结束就是此人的开始 p->end=p->start+p->process;   //刷新此人的所有信息(82-84) p->wait=p->start-p->arrive;if (p->wait<0) p->wait=0;p->next=temp->next;if (temp->next!=NULL)    //连接,画图理解 temp->next->prior=p;p->prior=temp;temp->next=p;break;}}if (flag==0)   //此人没有找到朋友,可怜,只能尾插 {p->prior=tail;tail->next=p;tail=p;}}}for (List *tt=head;tt!=NULL;tt=tt->next)   //输出名字 {printf("%s\n",tt->name);}double sum=0;for (List *temp=head;temp!=NULL;temp=temp->next)  //计算总等待时间 { sum+=temp->wait;}printf("%.1lf",sum/n);return 0;
}

7-2 银行排队问题之单窗口“夹塞”版 (30 分)相关推荐

  1. 7-48 银行排队问题之单窗口“夹塞”版 (30 分)(思路和详解+map做法)来呀Baby!

    一:题目 排队"夹塞"是引起大家强烈不满的行为,但是这种现象时常存在.在银行的单窗口排队问题中,假设银行只有1个窗口提供服务,所有顾客按到达时间排成一条长龙.当窗口空闲时,下一位顾 ...

  2. 7-4 银行排队问题之单窗口“夹塞”版 (30 分) C语言版

    排队"夹塞"是引起大家强烈不满的行为,但是这种现象时常存在.在银行的单窗口排队问题中,假设银行只有1个窗口提供服务,所有顾客按到达时间排成一条长龙.当窗口空闲时,下一位顾客即去该窗 ...

  3. 7-4 银行排队问题之单队列多窗口加VIP服务 (30 分)

    7-4 银行排队问题之单队列多窗口加VIP服务 (30 分) 说实话这道题挺恶心 有意思的,大模拟,主要的思路就是模拟时间轴. 题目描述 假设银行有K个窗口提供服务,窗口前设一条黄线,所有顾客按到达时 ...

  4. 7-3 银行排队问题之单队列多窗口服务 (25 分)

    7-3 银行排队问题之单队列多窗口服务 (25 分) 假设银行有K个窗口提供服务,窗口前设一条黄线,所有顾客按到达时间在黄线后排成一条长龙.当有窗口空闲时,下一位顾客即去该窗口处理事务.当有多个窗口可 ...

  5. 7-46 银行排队问题之单队列多窗口服务 (10 分)

    7-46 银行排队问题之单队列多窗口服务 (10 分) 假设银行有K个窗口提供服务,窗口前设一条黄线,所有顾客按到达时间在黄线后排成一条长龙.当有窗口空闲时,下一位顾客即去该窗口处理事务.当有多个窗口 ...

  6. 题353.2022暑期天梯赛训练-7-10 银行排队问题之单队列多窗口服务 (25 分)

    文章目录 题353.2022暑期天梯赛训练-7-10 银行排队问题之单队列多窗口服务 (25 分) 题目: 输入格式: 输出格式: 输入样例: 输出样例: **思路** **代码** 题353.202 ...

  7. 银行排队问题--事件链表+多窗口队列(数据结构课本)

    银行排队问题 事件驱动模拟问题 问题分析: ​ 银行开放了4个窗口,现在客户要从四面八方到银行办理业务:根据常识,到银行就少不了排队.我们排队按最短队伍排列,中途不切换队伍. ​ 现在随机生成到银行办 ...

  8. 易语言单窗口单ip软件源码_游戏工作室如何防封?游戏账号和IP被封的解决方法...

    现在的游戏公司,不管大的还是小的,多多少少都掌握了一些防封技术.把我们游戏打金者折腾的死去活来.关于游戏防封这方面的交流又很少,无奈!本方法除了部分不封号游戏外,还有个别疯狂封号必须让你立马死的游戏之 ...

  9. 一个html多个html文件怎么打开网页,Firefox如何单窗口多页面浏览

    Firefox单窗口多页面浏览方法. ①按下" Ctrl + 鼠标左键"点击链接. ②使用鼠标中鍵点击链接. 简介 火狐浏览器(Mozilla Firefox)是由Mozilla开 ...

最新文章

  1. 解题报告:luogu P2272 [ZJOI2007]最大半连通子图(tarjan缩点、递推DP、hash、set判重)
  2. c语言查找功能的怎么使用方法,求C语言实现查询功能(如果选择3,如何实现查询)...
  3. 【Centos 8】【Centos 7】【Docker】 安装 RabbitMQ
  4. TensorFlow学习笔记(七)feeds操作
  5. 优迈系统服务器初始化,优迈系统手机操作器服务器操作使用说明.pptx
  6. 哈师大计算机等级考试,哈尔滨师范大学教务处
  7. 对几个重要问题的阐述
  8. idea卸载不干净怎么办_fxfactory卸载不干净?Fxfactory及插件卸载教程
  9. Phoenix命令及语法
  10. Grafana 仪表盘和图形编辑器
  11. 文字在div中的垂直居中问题 div在页面中的水平垂直居中问题 vertical-align ??????
  12. UCF101动作识别数据集简介绍及数据预处理
  13. 小米盒子 android 动画特效,小米安卓电视一个屏保动画效果
  14. 用画图工具制作背景透明的图片总结
  15. 搜狗批量提交软件-批量提交网站链接
  16. 科沃斯扫地机器人抓不转_科沃斯扫地机器人一边转一边不转什么原因 科沃斯扫地机器人常见...
  17. mds部署服务器系统,Windows服务器2003年对MDS/IPS-8配置示例的iSCSI主机
  18. 大学物理 狭义相对论 思维导图总结
  19. 三电平半桥LLC谐振变换器电路仿真 采用频率控制方式 引入一定的移相角度
  20. jmeter的参数和请求后的参数不一致问题

热门文章

  1. LeetCode 247. 中心对称数 II(DP)
  2. db2 脚本运行错误返回错误原因_电脑运行错误代码大全,遇到报错请自己对照断电原因所在吧...
  3. php必须汉字,php怎么只保留汉字
  4. python计算球坐标系的积分_python – n球面坐标系到笛卡尔坐标系
  5. python中解决死锁的方法
  6. java流的传递方式是_java中数据的传递方式到底是怎样的!
  7. 模型评价 - 机器学习与建模中怎么克服过拟合问题?
  8. 在K40小破卡训练50层BERT Large的宝藏trick
  9. 限定域文本语料的短语挖掘(Phrase Mining)
  10. 从Java程序员进阶为架构师,全套16张图概括最全技能!建议收藏!