題意:
給一列數字,一個左指針 L 和一個右指針 R。
然後有7種操作。
最後輸出操作完的結果。
比賽時敲了2個小時才敲出來。。。各種弱。
解題思路:
觀察這7種操作,我們發現,除了翻轉,另外6種操作都是對於 L 或 R 這兩點進行的。
這不就是雙向隊列麼。
於是想到用三個隊列來儲存所有的數據:L 左邊的,L 到 R 的,R 右邊的。
對於翻轉操作,用一個變量記錄下當前的隊列是正向還是逆向。
然後每次操作的時候,如果當前的隊列是逆向的,則 L 相當於 R,R 相當於 L。
然後就沒有然後了,模擬吧。
貼上我簡化後的代碼。
[cpp]
#include <deque>
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
bool rev,first;
deque<int> A,B,C;
deque<int>::iterator it;
int pop_Front(deque<int>& d)
{
int tmp = d.front();
d.pop_front();
return tmp;
}
int pop_Back(deque<int>& d)
{
int tmp = d.back();
d.pop_back();
return tmp;
}
void Print()
{
if(first)
{
first = false;
printf("%d",*it);
}
else
printf(" %d",*it);
}
void Out()
{
first = true;
for(it=A.begin();it!=A.end();it++)
Print();
if(!rev)
for(it=B.begin();it!=B.end();it++)
Print();
else
for(it=B.end()-1;it!=B.begin()-1;it--)
Print();
for(it=C.begin();it!=C.end();it++)
Print();
puts("");
}
int main()
{
int L,R,Q,z,n,x;
scanf("%d",&z);
while(z--)
{
A.clear();
B.clear();
C.clear();
rev = false;
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&x);
B.push_back(x);
}
scanf("%d%d",&L,&R);
for(int i=1;i<L;i++)
A.push_back(pop_Front(B));
for(int i=R+1;i<=n;i++)
C.push_front(pop_Back(B));
scanf("%d",&Q);
char cmd[12],loc[5];
while(Q--)
{
scanf("%s",cmd);
if(cmd[0] == 'R')
{
rev = !rev;
continue;
}
scanf("%s",loc);
if(cmd[0] == 'M')
{
if(cmd[4] == 'L') //向左
{
if(loc[0] == 'L')
{
x = pop_Back(A);
!rev ? B.push_front(x) : B.push_back(x);
}
else
{
x = (!rev) ? pop_Back(B) : pop_Front(B);
C.push_front(x);
}
}
else //向右
{
if(loc[0] == 'L')
{
x = (!rev) ? pop_Front(B) : pop_Back(B);
A.push_back(x);
}
else
{
x = pop_Front(C);
!rev ? B.push_back(x) : B.push_front(x);
}
}
}
else if(cmd[0] == 'I')
{
scanf("%d",&x);
if(!rev)
loc[0] == 'L' ? B.push_front(x) : B.push_back(x);
else
loc[0] == 'R' ? B.push_front(x) : B.push_back(x);
}
else if(cmd[0] == 'D')
{
if(!rev)
loc[0] == 'L' ? B.pop_front() : B.pop_back();
else
loc[0] == 'R' ? B.pop_front() : B.pop_back();
}
}
Out();
}
return 0;
}