果然最重要的还是读懂题目,,
这个是动态的排队过程,黄线外面的人看那个队少了一个人就插进去,一开始想简单了,以为是大家都全部排好再开始,这个题目是黄线以内的排好后就开始,后面的人动态的插进去
#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;
}