背景:考虑一个你有N个6面骰子的游戏。模具的每一侧代表一个滚动:命令(COM)、科学(SCI)、工程师(ENG)、医学(MED)、安全(SEC)和一个未用于此问题的一侧。游戏的目标是使用挑战牌上的骰子,上面列出了解决挑战所需的不同角色例如,我可能有一张挑战卡,需要1个COM、1个SCI和1个MED所以如果我掷骰子得到1个com,1个sci和1个med,我就可以把它们应用到挑战卡上来解决挑战。
附加规则:除了骰子角色与挑战卡要求的1:1映射外,骰子还可以通过以下方式组合以更改其角色:
2个医学可以变成1个科学;2个科学可以变成1个医学。
2发可以变成1秒;2秒可以变成1发。
COM角色+任何其他角色都可以成为任何角色。所以COM+SEC可以成为工程师。
任何三个角色都可以成为不同的角色。所以com+sec+eng可以成为med。
问题:我想为挑战卡的要求生成所有可能的骰子组合的列表例如,一张挑战卡需要1个SCI、1个ENG和1个MED。我想我需要:
如果1个SCI、1个ENG和1个MED,完成(A、B、C)
如果1个SCI、1个ENG和2个SCI,完成(A、B、D)
如果1个SCI、1个ENG、COM和其他,完成(A、B、E)
如果1个SCI、1个ENG和3个其他,完成(A、B、F)
如果1个SCI,2秒,1个MED,完成(A,G,C)
如果1个SCI,2秒,2个SCI,完成(A,G,D)
如果1个SCI,2秒,COM和其他,完成(A,G,E)
如果1个SCI,2秒,3个其他,完成(A,G,F)
如果1个SCI,COM和其他,1个MED,完成(A,E,C)
如果1个SCI,COM和其他,2个SCI,完成(A,E,D)
如果1个SCI,COM和其他,COM和其他,完成(A,E,E)
如果1个SCI、COM和其他,3个其他,完成(A、E、F)
如果1个SCI,3个其他,1个MED,完成(A,F,C)
如果1个SCI、3个其他SCI和2个SCI,完成(A、F、D)
如果1个SCI,3个其他,以及COM和其他,完成(A,F,E)
如果1个SCI,3个其他,3个其他,完成(A,F,F)
此外,我还需要将最初的1个sci替换为2个med、com+其他设备和3个具有相同分组的其他设备。
问:尽管有这些例子,我还是在努力推导出一个可以用来编写代码的算法是否有人能提供一种算法,将交换角色与其他角色合并为所有有效组合列表的一部分?
最佳答案
你可以把它表示为语法您的起始状态是名义上的(直接的)挑战要求。您的边表示从该状态到另一状态的有效转换,每个边都显示反向转换。
例如,对于您的卡(SCI、ENG、MED),您将从三个元素的状态开始现在,您将使用每个转换规则包括可访问的状态(组合):
SCI => [MED, MED]
MED => [SCI, SCI]
b => [COM, a] for any (a, b), where a != b
d => [a, b, c] for any (a, b, c, d) where a, b, c, != d
您可以将这些规则中的每一个作为函数来表示。保留已经到达的状态(组合)列表。将问题视为图遍历,并使用标准算法从给定的开始状态查找图的闭包。对于初学者:
(SCI, ENG, MED)
apply rule 1
(ENG, MED^3) push this to your `search` list
apply rule 2
(SCI^3, ENG) push this to your `search` list
apply rule 3 to "SCI"
(a, COM, ENG, MED) for all `a` != "SCI"; push these ...
看看这是怎么回事?
每次通过时,您都会从列表中删除第一个项目,用规则对其进行更改,并将任何新状态推送到列表中。您需要跟踪已处理的状态,并检查每个状态中的元素数是否不超过
N
。你能根据那个提纲工作吗?