题意:给定n个箱子,编号为0~n-1。初始时,编号为0的箱子处于0,1处于1,,以此类推。可以进行五种操作。
move a onto b:将a与b上的箱子放回原位。然后将a放到b的上方
move a over b:将a上的箱子放回原位,b上方不动。然后将a堆积在b的上方。
pile a onto b:将b上方所有的箱子放回原位,然后将a以及a上方所有的箱子放到b的上方。
pile a over b:b上的箱子不动。将a以及a上方的所有箱子堆积到b的上方。
quit:退出操作,结束
求操作完成时各个位置箱子堆积情况。
思路:直接用栈模拟。很繁琐,要细心
#include<cstdio>
#include<iostream>
#include<cstring>
#include<string>
#include<map>
#include<stack>
using namespace std;
int m[30];
stack<int> g[30];
int main()
{
int n;
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
while(scanf("%d",&n)!=EOF)
{
char s[100];
for(int i=0;i<n;i++)
{
g[i].push(i);
m[i]=i;
}
while(scanf("%s",s))
{
if(s[0]=='q')break;
int a,b;
char s1[20];
scanf("%d%s%d",&a,s1,&b);
if(m[a]==m[b])continue;
if(s[0]=='m')
{
while(!g[m[a]].empty()&&g[m[a]].top()!=a)//把a上面的放回原处
{
int temp=g[m[a]].top();
g[temp].push(temp);
m[temp]=temp;
g[m[a]].pop();
}
g[m[a]].pop();
if(s1[1]=='n')//把b上面的放回原处,并在b上面放a
{
while(!g[m[b]].empty()&&g[m[b]].top()!=b)
{
int temp=g[m[b]].top();
g[temp].push(temp);
m[temp]=temp;
g[m[b]].pop();
}
g[m[b]].push(a);
m[a]=m[b];
}
else if(s1[1]=='v')//在b上面放a
{
g[m[b]].push(a);
m[a]=m[b];
}
}
else if(s[0]=='p')
{
stack<int> t;
while(g[m[a]].top()!=a)//保证有元素,不必判断是否为空
{
t.push(g[m[a]].top());
g[m[a]].pop();
}
t.push(g[m[a]].top());g[m[a]].pop();//取得a及a上面的块
if(s1[1]=='v')//将a及a上面的块堆到b上
{
while(!t.empty())
{
m[t.top()]=m[b];
g[m[b]].push(t.top());t.pop();
}
}
else if(s1[1]=='n')
{
while(g[m[b]].top()!=b)//b上面的放回原位
{
int temp=g[m[b]].top();
m[temp]=temp;
g[temp].push(temp);
g[m[b]].pop();
}
while(!t.empty())//将a及上面的放到b上
{
m[t.top()]=m[b];//
g[m[b]].push(t.top());t.pop();
}
}
}
}
for(int i=0;i<n;i++)
{
printf("%d:",i);
if(!g[i].empty())
{
stack<int> t;
while(!g[i].empty())
{
t.push(g[i].top());g[i].pop();
}
while(!t.empty())
{
printf(" %d",t.top());
t.pop();
}
}
printf("\n");
}
}
}