|
|
#include <bits/stdc++.h>
|
|
|
|
|
|
using namespace std;
|
|
|
//https://blog.csdn.net/weixin_30516243/article/details/95800585
|
|
|
//https://www.luogu.com.cn/problemnew/solution/UVA101?page=2
|
|
|
/**
|
|
|
总的来说就是碰到move就要把a上面的全部放回原处。
|
|
|
如果碰到 onto 就要把b上面的全部放到原处。 因为move是只移动a一个,
|
|
|
所以a上面的要归位,而pile是移一堆,所以不用。
|
|
|
onto是要和b贴在一起,所以b上面的要归位,而over是上方,不需要直接接触,
|
|
|
所以不用。。思路就是用栈来模拟,一开始就是n个栈。每个栈里都是一个元素,然后按照指令移,
|
|
|
在这个栈里pop()掉它,在另一个栈里push()进去。。 分四种情况来做移动,
|
|
|
每种情况处理方式不一样。要注意如果是一堆移过去,因为还是要按照这个顺序,
|
|
|
多以要先把这一堆放到另一个数组,再按顺序pushj进去。 模拟完输出即可。。
|
|
|
*/
|
|
|
|
|
|
const int maxn = 30;
|
|
|
int n;
|
|
|
vector<int> pile[maxn]; //每个pile[i]是一个vector
|
|
|
|
|
|
//找木块a所在的pile和height,以引用的形式返回调用者
|
|
|
void find_block(int a, int &p, int &h) {
|
|
|
for (p = 0; p < n; p++) //挨个堆去查找
|
|
|
for (h = 0; h < pile[p].size(); h++) //进入某个堆后,一个个开始查找,从下向上找
|
|
|
//如果找到,返回所在的堆p和高度h,通过&p和&h可以直接将数据修改后返回到主函数
|
|
|
if (pile[p][h] == a)
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
//把第p堆高度为h的木块上方的所有木块移回原位
|
|
|
void clear_above(int p, int h) {
|
|
|
//找到p堆h高度以上的所有木块
|
|
|
for (int i = h + 1; i < pile[p].size(); i++) {
|
|
|
int b = pile[p][i];
|
|
|
pile[b].push_back(b); //把木块b放回原位堆
|
|
|
}
|
|
|
//更改大小,相当于删除了vector里面多余的元素
|
|
|
pile[p].resize(h + 1); //pile只应保留下标0~h的元素
|
|
|
}
|
|
|
|
|
|
//把第p堆高度为h及其上方的木块整体移动到p2堆的顶部
|
|
|
void pile_onto(int p, int h, int p2) {
|
|
|
for (int i = h; i < pile[p].size(); i++)
|
|
|
pile[p2].push_back(pile[p][i]);
|
|
|
pile[p].resize(h);
|
|
|
}
|
|
|
|
|
|
//输出结果
|
|
|
void print() {
|
|
|
for(int i = 0; i < n; i++) {
|
|
|
printf("%d:", i);
|
|
|
for(int j = 0; j < pile[i].size(); j++)
|
|
|
printf(" %d", pile[i][j]);
|
|
|
printf("\n");
|
|
|
}
|
|
|
}
|
|
|
|
|
|
int main() {
|
|
|
int a, b;
|
|
|
cin >> n;
|
|
|
string s1, s2;
|
|
|
//共n堆,每堆1个,计为i号林块(0<=i<n),所以有两个概念,
|
|
|
// 一个是第几堆,一个是第几块,最开始是一样的数字,即 i=1时,第1堆里放着第1块木块
|
|
|
//但是随着移动变化,堆不变,但块会被移走或被其它林块盖上。
|
|
|
for (int i = 0; i < n; i++)
|
|
|
pile[i].push_back(i);
|
|
|
|
|
|
//读入命令
|
|
|
while (cin >> s1 >> a >> s2 >> b) {
|
|
|
int pa, pb, ha, hb;
|
|
|
//pa-->查找现在a木块存在于哪一堆内?
|
|
|
//ha-->a木块所在的高度,即索引号
|
|
|
find_block(a, pa, ha);
|
|
|
|
|
|
//同上
|
|
|
find_block(b, pb, hb);
|
|
|
|
|
|
//如果同一堆就不能动了,非法指令
|
|
|
if (pa == pb)
|
|
|
continue; //非法指令
|
|
|
|
|
|
//下面开始把共有的部分进行了抽象,节约代码
|
|
|
if (s2 == "onto")
|
|
|
clear_above(pb, hb);
|
|
|
|
|
|
if (s1 == "move")
|
|
|
clear_above(pa, ha);
|
|
|
|
|
|
pile_onto(pa, ha, pb);
|
|
|
}
|
|
|
//输出结果
|
|
|
print();
|
|
|
return 0;
|
|
|
} |