1014. Waiting in Line (30)

果然最重要的还是读懂题目,,

这个是动态的排队过程,黄线外面的人看那个队少了一个人就插进去,一开始想简单了,以为是大家都全部排好再开始,这个题目是黄线以内的排好后就开始,后面的人动态的插进去

#include<iostream>
using namespace std;
const int MaxN = 10001;
int N, M, K, Q;
int protime[MaxN];	
typedef struct Node * List;
int totletime[MaxN];	//记录每个人服务结束的时间
struct Node {
	int peo;
	int line;
	List Next;
	int nodetime;
};
struct head {
	List Next;
}a[MaxN];		//数组每一个元素是一个队伍,数组里的是头指针head
List NewNode(int peo, int line)	//建立新的节点,就是后面有人进队,就增加一个节点
{
	List node = new struct Node;
	node->line = line;
	node->Next = NULL;
	if (peo <= N)node->nodetime = protime[peo];	//初始化时每一队的第一个人的服务结束时间
	else
		node->nodetime = 0;	//非开始时每队的第一个人初始化为0
	node->peo = peo;
	return node;
}
void Insert(int i, int line)	//表示的是第i个人插进第line个队伍
{
	int peo = i;
	List tmp = NewNode(peo, line);
	List p = a[line].Next;
	if (!p)a[line].Next = tmp;
	else
	{
		while (p->Next)p = p->Next;
		tmp->nodetime = p->nodetime + protime[tmp->peo];//当前人的服务结束时间为前一个人服务结束时间加上当前人服务所需时间
		p->Next = tmp;
	}
	totletime[i] = tmp->nodetime;	//记录每个人的服务结束时间
}
void Showtime(int peo)	//这个题目的意思是17点之前接受服务就算可以,可以是17点前接受服务,17点后结束,不包括17点,这是大坑
{
	int sumtime = totletime[peo]-protime[peo];
	if (sumtime>=540)
		cout << "Sorry" << endl;
	else
	{
		sumtime = totletime[peo];
		int hour, minute;
		hour = sumtime / 60;
		minute = sumtime % 60;
		hour += 8;
		if (hour >= 10&&minute>=10)
			cout << hour << ":" << minute << endl;
		else if(hour<10&&minute>=10)
			cout << "0" << hour << ":" << minute << endl;
		else if (hour>=10 && minute < 10)
			cout << hour << ":" << "0" << minute << endl;
		else
			cout << "0" << hour << ":""0" << minute << endl;
	}
}
void Delete(int i)	//出队删除元素
{
	List p=a[i].Next;
	if (!p)return;
	a[i].Next = a[i].Next->Next;
	delete p;
}
int FindMin()	//最小队就是每个队的头谁先完成,谁就会空出一个,黄线外的人就可以插进来
{
	int mintime = 10000,mp;
	int i;
	for (i = 1; i <= N; i++)
		if (mintime > a[i].Next->nodetime)
		{
			mintime = a[i].Next->nodetime;
			mp = i;
		}
	Delete(mp);
	return mp;
}
int main()
{
	cin >> N >> M >> K >> Q;
	for (int i = 1; i <= N; i++)
	{
		a[i].count = 0;
		a[i].Next = NULL;
	}
	for (int i = 1; i <= K; i++)
		cin >> protime[i];
	for (int i = 1; i <= K; i++)
	{
		if (i <= N*M)	//小于N*M时,line就是余数
		{
			int line = i%N;
			if (line == 0)line = N;
			Insert(i, line);
		}
		else	//大于M*N,看哪个队伍先出来一个人
		{
			int min = FindMin();
			Insert(i, min);
		}
	}
	
	while (Q--)
	{
		int peo;
		cin >> peo;
		Showtime(peo);
	}
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值