题意:从左到右有n个木块,编号为0 ~ n-1,要求模拟一下4种操作(下面的a和b都是木块编号)。
1.move a onto b:把a和b上方的木块全部归位,然后把a摞到b上面
2.move a over b:把a 上方的木块全部归位,然后把a摞到b上面
3.pile a onto b: 把b 上方的木块全部归位,然后把a摞到b上面
4.pile a onto b: 把a摞到b上面
遇到quit终止一组数据。a和b在同一堆的指令是非法指令,应当忽略。
所有操作结束后,输出每个位置的木块列表,按照从底部到顶部的顺序。
思路:由于每堆木块的高度不确定,所以用vector存很合适。
#include<bits/stdc++.h>
using namespace std;
const int maxn = 30;
int n;
vector<int> v[maxn];
//找到木块a所在的p跟h(即v[i][j]的i,j)
void find_block(int a, int& p,int& h)//寻找木块p的位置
{
for(p = 0; p < n; p++)
{
for(h = 0; h < v[p].size(); h++)
{
if(v[p][h] == a) return ;
}
}
}
//把第p堆第h个木块上面的木块移回原位
void clear_above(int p,int h)
{
for (int i = h + 1; i < v[p].size(); i++)
{
int b = v[p][i];
v[b].push_back(b);//木块b放回原位
}
v[p].resize(h + 1);//v[p]只保留0~h的元素
}
//a摞到b上
void pile_onto(int pa, int ha,int pb)
{
for (int i = ha; i < v[pa].size(); i++)
{
v[pb].push_back(v[pa][i]);
}
v[pa].resize(ha);
}
//输出
void print()
{
for (int i = 0; i < n; i++)
{
printf("%d:", i);
for (int j = 0; j < v[i].size(); j++)
{
printf(" %d", v[i][j]);
}
printf("\n");
}
}
int main()
{
scanf("%d", &n);
for (int i = 0; i < n; i++) v[i].push_back(i);
int a, b;
string s1, s2;
while (cin >> s1)
{
if (s1 == "quit") break;//结束条件
cin >> a >> s2 >> b;
int pa, ha, pb, hb;
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;
}