输入整数 n ,表示有编号为 1到n 的木块,分别放在顺序排列编号为 1~n 的位置。
设 x 和 y 是木块块号。现对这些木块进行操作,操作指令有如下四种:
• mov x to y :把 x 、 y 上的木块放回各自原来的位置,再把 木块x 放到木块 y 上;
• mov x on y :把 x 上的木块放回各自的原来的位置,再把 x 放到包含了 y 的木块堆上;
• shift x to y :把 y 上的木块放回各自的原来的位置,再把 x 以及在 x 上面的木块放到 y 上;
• shift x on y :把 x 连同 x 上木块放到包含了 木块y 的堆上。
• 当输入 quit 时,结束操作并输出 0~n-1 位置上的木块情况。
• 在操作指令中,如果 x = y ,其中 x 和 y 在同一堆块,则该操作指令是非法指令。非法指令要忽略,并且不应影响块的放置。
输入格式:
输入的第一行给出一个整数 n ,表示木块的数目。本题设定 0 < n <= 50 。
然后给出一系列操作指令,每行一个操作指令。您的程序要处理所有命令直到遇到 quit 指令。
本题设定,所有的操作指令都是上面给出的格式,不会有语法错误的指令。
输出格式:
输出给出木块的最终状态。每个原始块位置 i ( 0<=i<n ,其中 n 是木块的数目)之后给出一个冒号。如果在这一位置至少有一个木块,则冒号后面输出一个空格,然后输出在该位置的一个木块列表,每个木块编号与其他块编号之间用空格隔开。在一行结束时不要在结尾加空格。
每个块位置要有一行输出(也就是说,要有 n 行输出,其中 n 是第一行输入给出的整数)。
输入样例1:
5
quit
输出样例1:
1: 1
2: 2
3: 3
4: 4
5: 5
输入样例2:
9
mov 9 to 1
mov 8 on 1
mov 7 on 1
mov 6 on 1
shift 8 on 6
shift 8 on 5
shift 2 on 1
shift 4 on 9
quit
输出样例2:
1: 1 9 2 4
2:
3: 3
4:
5: 5 8 7 6
6:
7:
8:
9:
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <ctype.h>
#include <stdlib.h>
#define maxn 30
int n;
int pile[maxn][maxn];
int pile_size[maxn];
//找到木块a所在的pile和height,以引用的形式返回调用者
void find_block(int a, int* p, int* h)
{
int i, j;
for (i = 0; i < n; i++) {
for (j = 0; j < pile_size[i]; j++) {
if (pile[i][j] == a) {
*p = i;
*h = j;
return;
}
}
}
*p = *h = -1; // not found
}
//把第p堆高度为h的木块上方的所有木块移回原位
void clear_above(int p, int h)
{
int i;
for (i = pile_size[p] - 1; i > h; i--) {
int b = pile[p][i];
pile[b][pile_size[b]] = b;
pile_size[b]++;
pile_size[p]--;
}
}
//把第p堆高度为h及其上方的木块整体移动到p2堆的顶部
void pile_onto(int p, int h, int p2)
{
int i;
for (i = h; i < pile_size[p]; i++) {
int b = pile[p][i];
pile[p2][pile_size[p2]] = b;
pile_size[p2]++;
}
pile_size[p] = h;
}
void print()
{
int i, j;
for (i = 0; i < n; i++) {
printf("%d:", i+1);
for (j = 0; j < pile_size[i]; j++)
printf(" %d", pile[i][j] + 1);
printf("\n");
}
}
int main()
{
int a, b;
char s1[5], s2[5];
int pa, pb, ha, hb;
int i, j;
scanf("%d", &n);
for (i = 0; i < n; i++) {
pile[i][0] = i;
pile_size[i] = 1;
}
while (scanf("%s%d%s%d", s1, &a, s2, &b) == 4) {
if (strcmp(s1, "quit") == 0) break;
find_block(a - 1, &pa, &ha);
find_block(b - 1, &pb, &hb);
if (pa == pb) continue;
if (strcmp(s2, "onto") == 0) clear_above(pb, hb);
if (strcmp(s1, "move") == 0) clear_above(pa, ha);
pile_onto(pa, ha, pb);
}
print();
return 0;
}