1014 Waiting in Line

1014 Waiting in Line

题目大意

就是给出的顾客服务时间,动态模拟每个顾客结束的时间,不过需要考虑的因素很多,有很多窗口,还有线外线内等

算法思想

  • 需要一个结构体,用来表示每个窗口,里面会有队伍的序号以及队首结束的时间
  • 动态表示时间从0到540,每当当前时间和队首结束的时间相等时,就弹出队首,此时如果有线外顾客,线外顾客进队
  • 最大的坑点是,如果是17点前接受的服务,哪怕下班了服务也得进行下去
  • 这题还是很复杂的,需要考虑的因素很多,变量也设了一堆,我第一次看懂题目后,脑子都乱死了,直接不想做了,但是仔细分析一下题目后,从容易的地方开始想,慢慢地就完成了这个复杂的题目

代码

写了很多注释,应该能看得懂吧

#include<iostream>
#include<vector>
#include<queue>
using namespace std;
typedef struct window {
	int ftime;//队伍第一个顾客结束服务的时间
	queue<int>people;//排队顾客
}window;
int main()
{
	int n, m, k, q;
	int i, j;
	cin >> n >> m >> k >> q;
	vector<int>cust;//每个顾客的时间
	vector<window>bank(n);//n个窗口的队伍
	for (i = 0; i < k; i++)
	{
		int t;
		cin >> t;
		cust.push_back(t);
	}
	vector<int>qu;//要询问的顾客队列
	for (i = 0; i < q; i++)
	{
		int quer;
		cin >> quer;
		qu.push_back(quer - 1);
	}
	int maxn = k;
	if (k > n * m)
	{
		maxn = n * m;
	}
	vector<int>nt(k);//记录每个顾客结束服务的时间,如果不能服务,就是0
	queue<int>line;//记录线外的顾客
	for (i = m * n; i < k; i++)
	{
		line.push(i);
	}
	j = 0;
	for (i = 0; i < maxn; i++)//线内的顾客进行排序
	{
		j = j % n;
		bank[j].people.push(i);
		if (bank[j].people.size() == 1)
		{
			bank[j].ftime = cust[i];
		}
		j++;
	}
	int nowtime = 0;
	for (nowtime = 0; nowtime <= 540; nowtime++)//动态模拟时间
	{
		for (i = 0; i < n; i++)//有可能不足m*n人
		{
			if (bank[i].people.empty())//如果当前窗口队伍为空,跳过
				continue;
			if (bank[i].ftime > 540)//坑点,一旦开始服务,哪怕下班也得继续下去
				nt[bank[i].people.front()] = bank[i].ftime;
			if (nowtime == bank[i].ftime)//到每队第一个顾客的结束时间
			{
				nt[bank[i].people.front()] = nowtime;//记录该顾客的服务时间
				bank[i].people.pop();
				if (!line.empty())//将线外的进行排队
				{
					bank[i].people.push(line.front());
					line.pop();
				}
				if (bank[i].people.empty())//如果线外没人了,队伍就空了,无法计算下面一行的时间
					continue;
				bank[i].ftime = cust[bank[i].people.front()] + nowtime;
			}
		}
	}
	for (i = 0; i < q; i++)//按询问队列输出
	{
		if (nt[qu[i]] == 0)
		{
			cout << "Sorry" << endl;
		}
		else
		{
			printf("%02d:%02d\n", (nt[qu[i]] + 480) / 60, (nt[qu[i]] + 480) % 60);
		}
	}
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值