好吧,算是一道难题吧。
思路:
1.读取队伍数,以次设置循环(如果队伍数等于0,直接终止循环)
2.读取每个队伍的人数,将读取到的队员编号,记录到一个数组之中,数组下标就是队员编号,对应的值为队员所在队伍
3.读取指令%s
4.如果开头是e,说明是入队
5.此时再读取入队人编号
6.如果此时队列是空的head==0,把这个入队人入队,放到head的位置,然后tail+1;同时找到这个人对应的队伍,将head记录为此时队伍的队尾编号,让将r_tail=head。
7.如果队列不是空的(如何判断队列不是空的呢?)
7.1如果队伍中有同队人,也就是队伍的队尾不等于0,
7.1.1如果当前同队人的队尾就是整个队伍的队尾
当前队伍的人的队尾的右端指向当前人,当前人的右端不管,r_tail=当前人,当前人入队,当前人的队伍的队尾改成tail,tail=tail+1;
7.1.2如果当前人同队人队尾不是整个队伍的尾端
那么当前人指向当前队尾人指向的人,当前人的队伍的队尾的人指向当前人,
当前人的队伍的队尾指向tail,tail=tail+1;
7.2如果队伍中没有同队人,也就是队伍的队尾等于0
那么就要直接将当前队员放在tail位置,更新队伍队尾为tail,让r_tail的人指向我,让后让r_tail等于tail,然后tail+1;
4.如果开头是d,说明首元素出列,出队的时候可是要按照队列顺序,而不是数组的下标顺序出队列!
5.如果当前没人了,说明当前的head=0,忽略此条操作
6.如果队伍中有人,也就是head!=0
6.1如果此时head下标的的队员所对应的队伍的队尾是自己,也就是这个队伍只剩下他一个人了,那么将这个元素对应队员对应队伍的队尾改成0,然后输出这个队员,head变成这个队员指向的位置。
6.2如果此时head下标对应的队员的队伍的队尾下标不等于head,说明此时输出队员编号,令head等于当前队员指向的那个坐标,
4.如果开头是S
那么清空所有数值,从新来过
ok,这道题终于算是解决了,谁能想到最后一个换行符还花了我10分钟去查呢。。。
查看答案:大佬们用的都是队中队的方法,记录每个队伍的优先级,然后进行弹出,插入即可。得益于c++的方便性,这里就不想在c语言中怎么实现了
再来捋一遍思路:(分支)
4.若e入
若没有队伍中的人
若有队伍中的人
若队伍中的人是队列尾
若队伍中的人不是队列尾
若d出
若空
若有人
若这个人是团队结尾
若这个人不是团队结尾
若s
ok分支完成,以后分支的时候,先把比较“大”的判断完成,然后再处理比较小的细节,即经过判断之后如何处理,最后还可以稍微优化一下代码。
代码:
#include<stdio.h>
int line[1000005][2]={0},head=0,tail=1,r_tail=0,tn=0,tm=0,no=0,cnt=0,mt[1000000]={0};
int main()
{
while(1)
{
//每次stop之后都要清空太麻烦,直接从新申请内存就好了
int t_end[1005]={0};
char oprate[10];
scanf("%d",&tn);
if(tn==0)
{
break;//没有队伍了,终于结束了啊!
}
cnt++;
printf("Scenario #%d\n",cnt);//输出他要的
for(int i=1;i<=tn;i++)//tn个队伍循环
{
scanf("%d",&tm);//记录队员
for(int j=1;j<=tm;j++)
{
scanf("%d",&no);//读取编号
mt[no]=i;//记录每个编号所对应的队伍
}
}
//读取完毕
//现在开始读取指令,由于读取指令没有停止,所以继续奥。
while(1)
{
scanf("%s",oprate);
//判断oprate的情况
if(oprate[0]=='E')//入队
{
scanf("%d",&no);//读取入队人
if(head==0)//空队伍
{
head++;
line[head][0]=no;
tail=tail+1;
t_end[mt[no]]=head;
r_tail=head;
}
else//不空
{
if(t_end[mt[no]]!=0)//说明队伍中有人
{
if(t_end[mt[no]]==r_tail)//整个队伍的尾端
{
line[tail][1]=line[t_end[mt[no]]][1];
line[t_end[mt[no]]][1]=tail;
t_end[mt[no]]=tail;
line[tail][0]=no;
r_tail=tail;
tail=tail+1;
}
else
{
line[tail][1]=line[t_end[mt[no]]][1];
line[t_end[mt[no]]][1]=tail;
t_end[mt[no]]=tail;
line[tail][0]=no;
tail=tail+1;
}
}
else//说明队伍中没有同队人,此时上一个队尾元素应该指向你
{
line[tail][0]=no;
line[r_tail][1]=tail;
t_end[mt[no]]=tail;
r_tail=tail;
tail=tail+1;
}
}
}
else if(oprate[0]=='D')//出队列
{
if(head==0)//空队列
{
continue;
}
else//队列中有人
{
if(t_end[mt[line[head][0]]]==head)//本队只剩我一个人了
{
t_end[mt[line[head][0]]]=0;
printf("%d\n",line[head][0]);
head=line[head][1];
}
else//也就是有人
{
printf("%d\n",line[head][0]);
head=line[head][1];
}
}
}
else if(oprate[0]=='S')
{
head=0;
tail=1;
r_tail=0;
printf("\n");
break;
}
}
}
return 0;
}
该博客主要讨论了一道编程题目,涉及使用C语言实现一个队列数据结构,包括入队、出队和清空操作。博主详细阐述了算法思路,从读取队伍和队员信息,到处理各种指令,如添加新队员(E)、删除首队员(D)和清空队列(S)。代码中使用二维数组line和辅助变量记录队伍状态,并通过循环和条件判断实现队列操作。

881

被折叠的 条评论
为什么被折叠?



