题目描述
有效命令:
- move a onto b:把a和b上所堆的所有木块复原,再把a放在b上面
- move a over b:把a上面所堆的所有木块复原,再把a放在b上面
- pile a onto b:把b上所堆的所有木块复原,再把a以及a上所堆的木块堆到b上
- pile a over b:把a以及a上的木块堆到b上
- quit:退出程序
共同点:
- 当命令包含onto的时候,复原b上的木块
- 当命令包含move的时候,复原a上的木块
- 其余命令都是将a(及a上的木块,复原a后a上不存在木块)放置于b上
综上:三种基础命令,一种是复原木块,一种是移动木块,一种是堆叠木块。
//
// Created by yoyoOvQ on 2021/2/3.
//
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
using namespace std;
int n;
const int maxn = 30;
vector<int> pile[maxn];
// 查找木块
void find_block(int block,int& p,int& h){
for (p = 0; p < n; ++p) {
for (h = 0; h < pile[p].size(); ++h) {
if (pile[p][h] == block) return;
}
}
}
// 清除木块-复原
void clear_block(int p,int h){
for (int i = h+1; i < pile[p].size(); ++i) {
int b = pile[p][i];
pile[b].push_back(b);
}
pile[p].resize(h+1);
}
// 堆叠木块
void stack_block(int pb,int pa,int ha){
for (int i = ha; i < pile[pa].size(); ++i) {
pile[pb].push_back(pile[pa][i]);
}
pile[pa].resize(ha);
}
int main(){
#ifndef ONLINE_JUDGE
ifstream cin("UVa/in/in-101.txt");
ofstream cout("UVa/out/out-101.txt");
#endif
cin >> n;
// 创建放木块堆vector数组
for (int i = 0; i < n; ++i)
pile[i].push_back(i);
int a, b;
string s1, s2;
// 读取命令 读到quit退出程序
while (cin >> s1 >> a >> s2 >> b){
int pa,pb,ha,hb; // 表存放ab木块的堆
find_block(a,pa,ha);
find_block(b,pb,hb);
if (pa == pb) continue;
if (s1 == "onto") clear_block(pb,hb);
if (s2 == "move") clear_block(pa,ha);
stack_block(pb,pa,ha);
}
// 打印输出
for (int i = 0; i < n; ++i) {
cout << i << ":";
for (int j = 0; j < pile[i].size(); ++j) {
cout << " " << pile[i][j];
}
cout << endl;
}
return 0;
}