Freda的队列
Problem Description
Freda有一个队列,最初它是空的。
现在Freda接到了一系列指令,每个指令包含一个整数x。
如果x>0,表示在队列开头加入一个数x。
如果x=0,表示把队列复制一份,并接在现有队列的末尾。
如果x=-1,表示弹出队列头部的数,并输出这个数值。
但是指令实在是太多了,Freda实在是计算不过来每次要输出什么数值,请你帮帮她吧。
Input
第一行包含一个整数N,表示指令的个数。
接下来N行每行一个整数x,描述每条指令。
Output
对于每条x=-1的指令,若此时队列不为空,则输出一个整数,表示从队头弹出的数。否则不进行任何操作。
Sample Input
8
3
4
0
-1
-1
-1
-1
1
Sample Output
4
3
4
3
Tip
对于50%的数据,1≤N≤1000
对于100%的数据,1≤N≤106,-1≤x≤109。
观察此题,我们可以知道,这是一道简单的模拟题,题目要求我们建出一个队列,并且包含向后复制这个队列,向前插入数,输出并删除第一个数这三个操作。
那么,我们就可以直接模拟出这道题的情况。
但是,我们考虑到,如果题目不断的复制后面的队列,将会导致我们所需要的时间过长。
所以,我们认真观察数据,发现N的范围在[1,106]内,那么,也就是说,最坏的情况,题目要求我们一直输出,也只能输出106个数。所以,我们的队列如果长度超过106,那么,后面的部分都可以舍弃,不需要再向后添加数。所以,我们得到如下的代码。
#include <cstdio>
using namespace std;
const int maxn=1000050;
int x[maxn<<1];
int head=maxn+1,tail=maxn;
int n,a;
inline int read()
{
int f=0,x=0;char c=getchar();
while (((c<'0')||(c>'9'))&&(c!='-'))
c=getchar();
if (c=='-')
c=getchar(),f=1;
while ((c>='0')&&(c<='9'))
x=(x<<3)+(x<<1)+c-'0',c=getchar();
return f?-x:x;
}
int main()
{
n=read();
while (n--)
{
a=read();
switch (a)
{
case -1:
if (head<=tail)
printf("%d\n",x[head++]);
break;
case 0:
for (int t=tail,q=head;((tail-1)<=(maxn<<1))&&(tail-head+51<=maxn)&&q<=t;q++)
x[++tail]=x[q];
break;
default:
x[--head]=a;
}
}
return 0;
}