题目大意:
一开始有n本书,书是垒起来放发,第一本在最上边。现在有m个操作,有2种操作类型:
add(xxx):将一本名为xxx的书放在书堆顶部;
rotate:将书堆顶部k本书颠个倒,如果当前书堆不足k本,则整个书堆颠倒。
自顶向下输出m个操作后的书堆。
题目分析:add操作很简单,随便弄一下就可以了。rotate操作的话,发现每次rotate操作只会影响堆顶的k本,所以将堆顶的k本拿出来,放到一个双端队列中,变向很方便。
多出来的从双端队列尾部放到一个栈中。最后逆序输出即可。
书名是字符串,所以直接对书的编号操作比较简单。
详情请见代码:
#include <iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 100005;
const int M = 40005;
int n,m,k,num,top,bot,nm,dir;
char name[N + M][5],op[20];
int ansque[N + M];
int mydeque[N + N + M];
void fuck()
{
int i;
gets(name[0]);
num = nm = 0;
dir = 1;
top = N + M;
bot = top + 1;
for(i = n - 1;i >= 0;i --)
{
gets(name[num]);
mydeque[-- bot] = num;num ++;
}
while(top >= bot && (top - bot) + 1 > k)
ansque[nm ++] = mydeque[bot ++];
while(m --)
{
gets(op);
if(*op == 'A')
{
for(i = 4;op[i] != ')';i ++)
if(isupper(op[i]))
name[num][i - 4] = op[i];
name[num][i] = '\0';
if(dir)
mydeque[++ top] = num;
else
mydeque[-- top] = num;
num ++;
if(dir)
{
while(top >= bot && top - bot + 1 > k)
ansque[nm ++] = mydeque[bot ++];
}
else
{
while(top <= bot && bot - top + 1 > k)
ansque[nm ++] = mydeque[bot --];
}
}
else
{
swap(top,bot);
dir^=1;
}
}
if(dir)
for(i = top;i >= bot;i --)
puts(name[mydeque[i]]);
else
for(i = top;i <= bot;i ++)
puts(name[mydeque[i]]);
for(i = nm - 1;i >= 0;i --)
puts(name[ansque[i]]);
}
int main()
{
while(scanf("%d%d%d",&n,&m,&k) != EOF)
{
fuck();
}
return 0;
}
/*
2 3 0
A
B
ADD(C)
ROTATE
ADD(D)
2 3 1
A
B
ADD(C)
ROTATE
ADD(D)
2 3 2
A
B
ADD(C)
ROTATE
ADD(D)
2 3 3
A
B
ADD(C)
ROTATE
ADD(D)
2 3 4
A
B
ADD(C)
ROTATE
ADD(D)
*/