这里有两个堆栈:
A: 1,2,3,4 <- Stack Top
B: 5,6,7,8
A和B将弹出到其他两个堆栈:C和D.
Example:
pop(A),push(C),pop(B),push(D).
If an item have been popped out , it must be pushed to C or D immediately.
那么,是否有算法可以找出C和D的所有可能性?
非常感谢!
答案 0 :(得分:0)
您可以生成堆栈中所有可能的弹出窗口的列表,然后模拟:
但是,当每个堆栈上只有两个元素时,会考虑重复。如果a被推到c,而b被推到d,那么推送它们的顺序并不重要。
def simulate(steps):
source={'a':range(4),'b':range(4,8)}
res = {'c':"",'d':""};
for i,step in enumerate(steps):
res[step[1]]+=str(source[step[0]].pop())
# this is what each stack will look like
return res['c']+'-'+res['d']
def steps(a_left,b_left):
ret = []
if a_left>0:
substeps = steps(a_left-1,b_left)
ret.extend( [ x + [('a','c')] for x in substeps] )
ret.extend( [ x + [('a','d')] for x in substeps] )
if b_left>0:
substeps = steps(a_left,b_left-1)
ret.extend( [ x + [('b','c')] for x in substeps] )
ret.extend( [ x + [('b','d')] for x in substeps] )
if(len(ret)==0):
return [[]]
return ret;
结果:
>>> [x for x in steps(1,1)]
[[('b', 'c'), ('a', 'c')], [('b', 'd'), ('a', 'c')], [('b', 'c'), ('a', 'd')], [
('b', 'd'), ('a', 'd')], [('a', 'c'), ('b', 'c')], [('a', 'd'), ('b', 'c')], [('
a', 'c'), ('b', 'd')], [('a', 'd'), ('b', 'd')]]
>>> [simulate(x) for x in steps(1,1)]
['73-', '3-7', '7-3', '-73', '37-', '7-3', '3-7', '-37']
>>> len(set([simulate(x) for x in steps(4,4)]))
5136
如果我们考虑只有一个目标堆栈的两个堆栈,我们可以在(2 * n)!/(n!)^ 2找到唯一堆栈的数量。这与8个元素的排列数相同,其中4个是'A',其中4个是'B'。然后我们可以通过将它们分成子集来将它们分配给每个单独的堆栈 - 每个堆栈具有N个唯一数字的子集的数量将是2 ^(2 ^ n)
(2^(2*n))/((2*n)!/(n!)^2)
但是,我没有看到更有效地生成这些内容的方法。
答案 1 :(得分:0)
我有个主意,但不知道这是否正确:
设置一个有8位的堆栈,1表示一个弹出,0表示B弹出(只要确保有四个1和四个0)。
所以答案就是找出8位数组合的所有可能性。
然后迭代8位以弹出A或B.
以下是代码:
public class Test {
public static void generate(int l, int[] a) {
if (l == 8) {
if (isValid(a)) {
for (int i = 0; i < l; i++) {
System.out.print(a[i]);
}
System.out.println();
}
} else {
for (int i = 0; i < 2; i++) {
a[l] = i;
generate(++l, a);
--l;
}
}
}
// the combination must have four 0 and four 1.
public static boolean isValid(int[] a) {
int count = 0;
for (int i = 0; i < a.length; i++) {
if (a[i] == 0) count++;
}
if (count != 4) return false;
return true;
}
public static void main(String[] args) {
generate(0, new int[8]);
}
}
答案 2 :(得分:0)
C和D的内容可以按任意顺序写成四个A和四个B的序列。
AABABBBA (表示弹出A两次,然后B弹一次,然后A弹一次等)
确实有 8选择4 这样的序列。所以只需iterate over every such sequence (“不重复的组合”)即可获得答案。