课后作业:搬砖块
仿真是计算机科学中的重要研究领域。而你身为一名初级研究员,现在有一个简单的小任务。通过你的仿真程序,模拟以下情况。
在你面前的桌子上有一条机械臂和 n 个砖块。这 n 个砖块按 1,2,…,n−2,n−1,n 顺序依次被编号,并且被排成一行放置在桌上(初始状态)。
机械臂有以下2种指令:
- clear a 把 a 上方的木块全部放回其初始位置
- move a over b 把 a 和 a 上方的所有木块(如果有)放在 b 所在木块堆的最上面。
如果有非法指令(例如:a和b在同一堆),应当忽略,非法指令不会造成任何影响。
所有操作输入完毕后,从左到右,从下到上输出每个位置的木块编号。
输入格式
第一行:两个整数n,m,n表示桌上初始的木块数量 (2<=n<=25) m表示将要执行的操作数量 随后m行:一条机械臂操作指令。(5 <= m <= 10000)
输出格式
输出是桌上木块的的最终状态。 输出共有 n 行,每一行的开头编号为 行数 并紧跟一个冒号。表示编号为 i(1 < i ≤ n,其中n是块数)的木块的最原始位置。 如果该位置上有木块,则从下到上,先输出一个空格再输出木块的编号。
输入样例
10 8
move 8 over 1
move 6 over 1
move 10 over 1
move 3 over 2
move 9 over 2
move 7 over 3
move 9 over 6
clear 10
输出样例
1: 1 8 6 10
2: 2 3
3:
4: 4
5: 5
6:
7: 7
8:
9: 9
10:
样例解释
move 8 over 1 木块8移到木块1上方
move 6 over 1 木块6移到木块1、8上方
move 10 over 1 木块10移到木块1、8、6上方
move 3 over 2 木块3移到木块2上方
move 9 over 2 木块9移到木块2、3上方
move 7 over 3 木块7移到木块2、3、9上方
move 9 over 6 木块9、7移到木块1、8、6、10上方
clear 10 木块10上方的木块9、7回到最初的位置
答案程序
#include<bits/stdc++.h>
using namespace std;
const int N=30;
int n,m;
int l[N];//木块所在的列
int cnt[N];//当前这列有多少木块
int g[N][N];//目前状态:多少列第几个
void init(){
for(int i=1;i<=n;i++){
l[i]=i;
cnt[i]=1;
g[i][1]=i;
}
}
void clear(int a){
int nl=l[a];//所在列
int id=1;//a所在的下标
while(g[nl][id]!=a){//找出第几个是a
id++;
}
for(int i=id+1;i<=cnt[nl];i++){
int nm=g[nl][i];//当前木块状态
if(nm==nl){//当前木块是当前列
g[nl][id]=nm,id++;//放回木块处理
}
else{
l[nm]=nm;//转列
g[nm][++cnt[nm]]=nm;//放回木块处理
}
}
cnt[nl]=id;//少了a上面的木块
}
void move(int a, int b){
int nla=l[a],nlb=l[b];
if(nla==nlb){//同列不变
return ;
}
int id=1;
while(g[nla][id]!=a){//找出第几个是a
id++;
}
for(int i=id;i<=cnt[nla];i++){
int nm=g[nla][i];
l[nm]=nlb;//转列
g[nlb][++cnt[nlb]]=nm;//依次放木块
}
cnt[nla]=id-1;//少了a和上面的木块
}
void print(){
for(int i=1;i<=n;i++){
cout<<i<<": ";
for(int j=1;j<=cnt[i];j++){
cout<<g[i][j]<<" ";
}
puts("");
}
}
int main(){
cin>>n>>m;
init();
while(m--){
string a;
int b;
cin>>a>>b;
if(a=="clear"){
clear(b);
}
else{
string c;
int d;
cin>>c>>d;
move(b,d);
}
}
print();
return 0;
}