问题
说你有N个堆命名小号1至S Ñ,其中每个小号ķ(k = 1至N)中包含数k的N份。
例如,当N = 3时,堆栈如下所示:
1 2 3 <- top of stack
1 2 3
1 2 3 <- bottom of stack
=======
1 2 3 <- stack index
这里有3个索引为1、2和3的堆栈,每个堆栈包含N个自己索引的实例。
目的是重新排列N个堆栈,以使它们中的每个堆栈都按从上到下的顺序完全包含数字1到N。
例如,对于N = 3,目标是将堆栈重新排列为:
1 1 1
2 2 2
3 3 3
=======
1 2 3
您可以对堆栈执行的唯一操作是从其中一个堆栈中取出最高编号(弹出),然后立即将其放在另一个堆栈顶部(按下)。这要遵守以下规定:
如果一个数字小于或等于该堆栈上的最高编号,则只能将其压入堆栈。
例如
1
可以推到堆栈上用1
,2
或3
在顶部,但是一个2
只能与一个推到堆栈2
或3
在顶部(或更高)。这样的结果是堆栈总是从上到下单调增加。
可以从中弹出任何非空堆栈,并且在满足前一个项目符号的情况下,可以将任何堆栈压入其中。
可以将任何数字压入空堆栈。
堆栈没有最大高度限制。
不能创建或销毁堆栈,始终有N个堆栈。
挑战在于决定完成哪些弹出操作以完成堆栈交换,不一定要用最少的动作,而是要确保安全。
(练习一副纸牌是感觉问题的好方法。)
挑战
编写一个程序或函数,该程序或函数采用正整数N(保证为3或更大)。打印或返回一个字符串,该字符串表示从初始状态重新排列堆栈所需的所有弹出按钮操作:
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
=============
1 2 3 4 5
(N = 5例)
到最终状态:
1 1 1 1 1
2 2 2 2 2
3 3 3 3 3
4 4 4 4 4
5 5 5 5 5
=============
1 2 3 4 5
输出中的每一行都必须包含两个数字,并用空格分隔。第一个数字是要从中弹出堆栈的索引,第二个数字是要推入的堆栈索引。按顺序执行所有行的操作应正确排列堆栈,而不会违反任何规则。
例如,这是N = 3情况的潜在有效输出:
1 2 [move the top number on stack 1 to the top of stack 2]
1 2 [repeat]
1 2 [repeat]
3 1 [move the top number on stack 3 to the top of stack 1]
2 3 [etc.]
2 3
2 3
2 1
2 1
2 1
3 1
3 1
3 1
3 2
1 2
1 2
1 2
1 3
2 3
2 3
2 3
1 2
3 2
3 1
笔记
您的输出也并不需要是最佳的,唯一正确的。即,您不需要最小化弹出和推送的次数。
- 因此,如果说,如果反复采取一些措施并立即撤消措施,那将是可以的。
- 例如
2 2
,也允许一招弹出并推送到同一堆栈(尽管毫无意义)。
您的输出确实需要确定性和有限性。
请记住,堆栈具有基于1的索引。不允许从0开始的索引。
大于9的N当然应该和个位数N一样工作。
如果需要,您可以使用任何两个不同的非数字可打印ASCII字符代替空格和换行符。输出中的尾随换行符(或换行符替换)很好。
计分
以字节为单位的最短代码获胜。决胜局是最高投票的答案。
如果您可以证明算法是最佳的,那么无价的布朗尼积分。
-._(._.)_.-
N=3
最佳情况,您包括了可能的输出吗?