从左到右有n个木块,编号为0~n-1,要求模拟以下4种操作(下面的a和b都是木块编号)。
- move a onto b:把a和b上方的木块全部归位,然后把a摞在b上面。
- move a over b:把a上方的木块全部归位,然后把a放在b所在木块堆的顶部。
- pile a onto b:把b上方的木块全部归位,然后把a及上面的木块整体摞在b上面。
- pile a over b:把a及上面的木块整体摞在b所在木块堆的顶部。
遇到quit时终止一组数据。a和b在同一堆的指令是非法指令,应当忽略。
样例输入:
1234
样例输出:
1234-> 3087-> 8352-> 6174-> 6174
#include <iostream>
#include <string>
#include <vector>
using namespace std;
const int N = 30;
vector<int> pile[N];
int n;
void findBlock(int a,int &p,int &h){
for(p = 0; p < n; p++)
for(h = 0; h < pile[p].size(); h++)
if(pile[p][h] == a) return;
}
//把第p堆高度为h的木块上方的所有木块移回原位
void clearAbove(int p,int h){
for(int i = h+1; i < pile[p].size(); i++){
int b = pile[p][i];
pile[b].push_back(b); //把木块b放回原位
}
pile[p].resize(h+1); //pile 只应保留下标0~h 的元素
}
//把第p堆高度为h及其上方的木块整体移动到p2 堆的顶部
void pileOnto(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 argc, char** argv) {
string sa, sb;
int a, b;
cin>> n;
for(int i = 0; i < n; i++) pile[i].push_back(i);
while(cin>> sa>> a>> sb>> b){
int pa, pb, ha, hb;
findBlock(a, pa, ha);
findBlock(b, pb, hb);
if(pa == pb) continue;
if(sb == "onto") clearAbove(pb, hb); //如果是onto就把b上面的还原。
if(sa == "move") clearAbove(pa, ha); //如果是move把a上面的还原.
pileOnto(pa, ha, pb);
}
print();
return 0;
}