题意:(转自https://www.cnblogs.com/zhurb/p/5839701.html)
给定一个长度n,有0~n-1编号的箱子和位置,起始个编号的箱子放在相同编号的位置。
有一系列操作:
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箱最上方。
要求输出最后每个位置的箱子。
题解:
本来不应该有什么难度的,只是基础不扎实的我太菜了......
开5个数组记录每个位置的底层箱子和顶层箱子以及每个箱子的位置、上层、和下层,模拟即可......
注意:
让人调了半小时的一个重大失误:
移动整块时不仅要该当前箱子的pos,还要改它上面所有箱子的pos!!!
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
int n,a,b;
int up[30],down[30],pos[30];
int top[30],base[30];
inline void move(int val,int des) {
int pre=pos[val],tmp=top[pre];
if (down[val]==-1) base[pre]=-1;
up[down[val]]=-1;
top[pre]=down[val];
// pos[val]=des;
for (int i=val;~i;i=up[i])
pos[i]=des;
down[val]=top[des];
up[top[des]]=val;
top[des]=tmp;
if (down[val]==-1) base[des]=val;
}
inline void clear(int val) {
for (int i=up[val];~i;i=up[i])
move(i,i);
// for (int i=top[pos[val]];i^val;i=down[i])
// move(i,i);
}
int main() {
// freopen("poj 1208.in","r",stdin);
memset(up,-1,sizeof(up));
memset(down,-1,sizeof(down));
scanf("%d",&n);
for (int i=0;i<n;++i)
top[i]=base[i]=pos[i]=i;
char s1[5],s2[5];
while (scanf("%s",s1)&&s1[0]^'q') {
scanf("%d%s%d",&a,s2,&b);
if (s1[0]=='m'&&s2[2]=='t') {//move a onto b
clear(a);
clear(b);
move(a,pos[b]);
} else if (s1[0]=='m'&&s2[2]=='e') {//move a over b
clear(a);
move(a,pos[b]);
} else if (s1[0]=='p'&&s2[2]=='t') {//pile a onto b
clear(b);
move(a,pos[b]);
} else {//pile a over b
move(a,pos[b]);
}
}
for (int i=0;i<n;++i) {
printf("%d: ",i);
if (base[i]==-1) puts("");
else {
for (int cur=base[i];~cur;cur=up[cur])
printf("%d ",cur);
puts("");
}
}
return 0;
}