例题5-2 木块问题(The Blocks Problem,Uva 101)
欢迎访问我的Uva题解目录哦 https://blog.****.net/richenyunqi/article/details/81149109
题目描述
题意解析
从左到右有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在同一堆的指令是非法指令,应当忽略。
C++代码
#include<bits/stdc++.h>
using namespace std;
vector<vector<int>>blocks(25);
void findBlock(int id,int&p,int&h){//确定编号为id的木块的位置
for(p=0;p<blocks.size();++p)
for(h=0;h<blocks[p].size();++h)
if(blocks[p][h]==id)
return;
}
void reset(int p,int h){//将第p个木快堆高度h以上的木块复归原位
for(int i=h+1;i<blocks[p].size();++i)
blocks[blocks[p][i]].push_back(blocks[p][i]);
blocks[p].resize(h+1);
}
void pile(int pa,int pb,int ha){//将第pa个木块高度ha以上的木块摞在第pb个木块堆的顶部
for(int i=ha;i<blocks[pa].size();++i)
blocks[pb].push_back(blocks[pa][i]);
blocks[pa].resize(ha);
}
int main(){
int N,a,b;
cin>>N;
string s1,s2;
for(int i=0;i<N;++i)//初始化每个木块堆
blocks[i].push_back(i);
while(cin>>s1>>a>>s2>>b){
int pa,pb,ha,hb;
findBlock(a,pa,ha);//搜索编号为a的木块的位置
findBlock(b,pb,hb);//搜索编号为b的木块的位置
if(pa==pb)//如果位于同一个木块堆
continue;//略去以下步骤
if(s1=="move"){
if(s2=="onto")
reset(pb,hb);//把b上方的木块全部归位
reset(pa,ha);//把a上方的木块全部归位
blocks[pb].push_back(a);//把a摞在b上面
blocks[pa].pop_back();
}else if(s1=="pile"){
if(s2=="onto")
reset(pb,hb);//把b上方的木块全部归位
pile(pa,pb,ha);//把a及上面的木块整体摞在b所在木块堆的顶部
}
}
for(int i=0;i<N;++i){//输出
printf("%d:",i);
for(auto j:blocks[i])
printf(" %d",j);
puts("");
}
return 0;
}