可以看成有n块板子,每块板子上面标记有0,1,……n - 1数字。如下图所示:
对这些板子有如下几个操作:
1、move a onto b:
上述的a和b都是板子的标号。将板子a放到b上面,且将a和b板子上的所有的板子都放回他们的初始位置。
2、move a over b:
上述的a和b都是板子的标号。将板子a放到b板子所在堆的最上面,且将板子a上的所以板子都放回他们的初始位置。
3、pile a onto b:
上述的a和b都是板子的标号。将板子a及a上的所有板子都放到b上,且将板子b上的所有板子都放回他们的初始位置。
4、pile a over b:
上述的a和b都是板子的标号。将板子a及a上的所有板子都放到b板子所在堆的最上面。
这里要提醒一下,进行3操作时首先应该把a该移过去的 存起来, 然后move b,再把刚才存的加上去。因为如果先move的话会把一些板子移到a上,此时再加就错了。。
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <iostream>
#include <algorithm>
#include <map>
#include <vector>
#include <set>
using namespace std;
#define N 100
int n;
int s[N][N], top[N], pos[N]; //pos是指i的当前位置
void ini() //初始化
{
for(int i = 0; i < n; i++)
{s[i][0] = i; pos[i] = i;top[i]=1;}
}
void move(int id, int a) //把某堆a上边的清空
{
//printf("top[id]=%d a=%d\n",top[id], a);
while(s[id][top[id]-1]!=a)
{
// printf("haha\n");
int tmp = s[id][top[id]-1];
top[id]--;
s[tmp][top[tmp]++] = tmp;
pos[tmp] = tmp;
}
}
void print() //输出
{
for(int i = 0; i < n; i++)
{
printf("%d:",i);
for(int j = 0; j < top[i]; j++)
printf(" %d", s[i][j]);
printf("\n");
}
}
int main()
{
while(~scanf("%d", &n))
{
char a1[N], a2[N];
int a, b;
ini();
while(scanf("%s",a1))
{
if(strcmp(a1, "quit")==0)
break;
scanf("%d%s%d", &a, a2, &b);
if(a==b||pos[a]==pos[b])
continue;
if(a1[0]=='m')
{
move(pos[a],a);
top[pos[a]]--;
pos[a] = pos[b];
if(a2[1]=='n')
move(pos[b], b);
s[pos[b]][top[pos[b]]++] = a;
}
else
{
int tmp[N],cnt=0;
int id = pos[a];
while(1)
{
tmp[cnt++] = s[id][top[id]-1];
top[id]--;
pos[tmp[cnt-1]] = pos[b];
if(tmp[cnt-1]==a)
break;
}
if(a2[1]=='n')
move(pos[b], b);
for(int i = cnt-1; i >= 0; i--)
s[pos[b]][top[pos[b]]++]=tmp[i];
}
}
print();
}
return 0;
}