You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

94 lines
3.5 KiB

2 years ago
#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
/**
  
j
*/
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;
}