1 条题解
-
0
题目分析
我们需要模拟木块堆叠的四种操作:
move A onto B
、move A over B
、pile A onto B
和pile A over B
。关键在于如何高效维护木块的位置关系,并在不同操作下正确更新木块的堆叠状态。
解题思路
1. 数据结构设计
- 链表表示木块堆:
- 每个位置用一个链表表示,链表的节点存储木块编号(
data
)和指向下一个木块的指针(next
)。 - 初始时,位置 的链表仅包含一个节点,其
data = i
,next = NULL
。 - 链表头代表堆底,链表尾代表堆顶。
- 每个位置用一个链表表示,链表的节点存储木块编号(
2. 操作分类处理
-
move A onto B
:- 操作目标:将 移到 上,且 和 上方的木块全部归位。
- 步骤:
- 将 上方所有木块归位(从 的
next
开始遍历,逐个放回初始位置)。 - 将 上方所有木块归位(同上)。
- 将 的
next
指向 的next
,并更新 的next
为 。
- 将 上方所有木块归位(从 的
-
move A over B
:- 操作目标:将 移到 所在堆的顶部,仅归位 上方的木块。
- 步骤:
- 将 上方所有木块归位。
- 找到 所在链表的尾节点,将尾节点的
next
指向 。 - 断开 与原位置的连接(设置原位置的
next
为NULL
)。
-
pile A onto B
:- 操作目标:将 及其上方所有木块移到 上,仅归位 上方的木块。
- 步骤:
- 将 上方所有木块归位。
- 断开 与原位置的连接(设置原位置的
next
为NULL
)。 - 将 的
next
指向 。
-
pile A over B
:- 操作目标:将 及其上方所有木块移到 所在堆的顶部,不归位任何木块。
- 步骤:
- 找到 所在链表的尾节点。
- 将尾节点的
next
指向 。 - 断开 与原位置的连接。
关键优化
- 归位操作的高效实现:
- 归位时直接遍历链表,将木块放回初始位置(
data
值对应的链表),时间复杂度为 ,其中 为木块堆的高度。
- 归位时直接遍历链表,将木块放回初始位置(
- 链表尾节点快速定位:
- 维护每个链表的尾节点指针,避免每次从头遍历,可将尾节点查找时间从 优化到 。
- 操作分类处理:
- 通过条件判断区分四种操作,避免冗余步骤。
复杂度分析
- 时间复杂度:
- 单次操作的最坏情况为 (需遍历整个链表归位木块)。
- 总复杂度为 ,其中 为操作次数。
- 空间复杂度:
- 使用 条链表存储木块,空间为 。
#include<cstdio> #include<cstdlib> #include<cstring> using namespace std; struct node { int data; struct node *next; }; int main() { struct node *p, *q, *t, *head[30], *pa, *pb, *qa, *qb, *tt; int i, j, d, n; scanf("%d", &n); qa = NULL; qb = NULL; for(i = 0; i <= n-1; i++) { p = (struct node *)malloc(sizeof(struct node)); p -> data = i; p -> next = NULL; head[i] = p; } char aa[10], bb[10]; int a, b; getchar(); while(scanf("%s", aa)) { qa = NULL; qb = NULL; if(strcmp(aa, "quit") == 0) { break; } scanf("%d%s%d",&a, bb, &b); if(a == b) continue; for(i = 0; i <= n-1; i++) { t = head[i]; while(t != NULL) { if(t->data == a) { pa = t; } if(t->next != NULL && t->next->data == a) { qa = t; } if(t->data == b) { pb = t; } if(t->next != NULL && t->next->data == b) { qb = t; } t = t->next; } } struct node *ta, *tb; ta = pa; while(ta->next != NULL) { ta = ta->next; } tb = pb; while(tb->next != NULL) { tb = tb->next; } if(ta == tb) continue; if(strcmp(aa, "move") == 0) { if(qa != NULL) { qa->next = NULL; } else { head[pa->data] = NULL; } t = pa->next; while(t != NULL) { head[t->data] = t; tt = t->next; t->next = NULL; t = tt; } if(strcmp(bb, "onto") == 0) { t = pb->next; while(t != NULL) { head[t->data] = t; tt = t->next; t->next = NULL; t = tt; } pb->next = pa; } else if(strcmp(bb, "over") == 0) { t = pb; while(t->next != NULL) { t = t->next; } t->next = pa; pa->next = NULL; } } else if(strcmp(aa, "pile") == 0) { if(qa != NULL) { qa->next = NULL; } else { head[pa->data] = NULL; } if(strcmp(bb, "onto") == 0) { t = pb->next; while(t != NULL) { head[t->data] = t; tt = t->next; t->next = NULL; t = tt; } pb->next = pa; } else if(strcmp(bb, "over") == 0) { t = pb; while(t->next != NULL) { t = t->next; } t->next = pa; } } } for(j = 0; j <= n-1; j++) { t = head[j]; printf("%d:", j); while(t != NULL) { printf(" %d", t->data); t = t->next; } printf("\n"); } return 0; }
- 链表表示木块堆:
- 1
信息
- ID
- 209
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者