描述
幼儿园的小朋友在食堂门口排队买饭,他们的编号为 1, 2, 3, …, n。有些小孩子i 喜欢找一个帮他排队的好朋友Pi,如果i 自己开始排队时Pi 已经排在队列中,那么i 就插到Pi 和他后面小孩子的之间。如果此时Pi 并不在队列中,则i 就老老实实的排在队尾。注意:有可能两个孩子i≠j 的好朋友Pi=Pj 相同,不愿意插队的小朋友Pi=0。
例如,有 4 个小孩,P1=P2=0,P3=P4=1。下面是一个可能的事件序列:
事件 队列(最左边是队首) 注释
小孩 1 排队 1
小孩2 排队 1 2
小孩3 排队 1 3 2 P3=1,小孩1 仍在队中
队首小孩买到饭后离开 3 2 小孩1 离开
小孩4 排队 3 2 4 P4=1,小孩1 不在队中
队首小孩买到饭后离开 2 4 小孩3 离开
队首小孩买到饭后离开 4 小孩2 离开
队首小孩买到饭后离开 (空) 小孩4 离开
-
输入
-
输入第一行包括一个数 n。表示一共有n 个小孩。以下2n 行每行包含两个数i, j。如果i<0 则表示队首的孩子已经买到饭,离开队列;
如果i>0 则表示孩子i来到食堂,他的好朋友编号为Pi=j(j=0 表示他不想插队)。输入保证每个孩子恰好来到食堂一次,并且都能买到饭。
输出
-
输出一行,包含 n 个整数,依次为每个买到饭的孩子编号。
1<=n<=10^5
模拟题,用队列实现
#include<stdio.h> main() { long int n; int te; int i,j; int temp1,temp2; int up; int a[100001]; scanf("%ld",&n); up=0; for(te=1;te<=2*n;te++) { scanf("%d %d",&temp1,&temp2); if(temp1>0&&temp2==0) { a[up++]=temp1; } if(temp1>0&&temp2>0) { for(i=0;i<up;i++) { if(a[i]==temp2) break; } if(i==up) a[up++]=temp1; else { for(j=up;j>i+1;j--) a[j]=a[j-1]; a[i+1]=temp1; up++; } } if(temp1<0) { printf("%d ",a[0]); for(i=0;i<up;i++) a[i]=a[i+1]; up--; } } }