九枚硬币翻转问题

这个例子取自于《Java语言程序设计--进阶篇》一书。


问题描述:

在一个3*3的矩阵中,每一个格子表示一枚硬币,其中一些硬币正面朝上,另一些正面朝下。需要经过一些移动,使得所有的硬币都正面朝下。

而每一次移动的规则是这样的:每次翻转一个硬币,那么这枚硬币的上下左右的硬币也都要重新翻转一次。

经过尽量少的翻转次数,使得所有硬币都正面朝下,那么结束。


难点:

这个问题的难点在于怎样对问题进行抽象,咋一看感觉根本摸不着方向。书上的解法是这样的,将这个问题抽象成为一个图问题。因为这个3*3的矩阵所有的状态是有限的,每个硬币只可能是正和反,所以矩阵所有的状态为 2^9 = 512。那么,就可以对每个状态进行编码,将每个状态对应为一个二进制数。正好是0~511。而在这些状态中,每一个状态只能向固定的另外几个状态发生转变。在这些条件下,就可以进行抽象了。将这512个状态看作是图中的顶点,而从一个状态到另外一个状态的转变可以看作是这两个顶点间的边。在对状态进行编码的时候,最终状态因为是每一个硬币朝向都一致,所以是511 = (111111111)。所以从某一个状态通过一些翻转到最终状态的过程可以看作是,在图中的某一点找到一条路径达到编号为511顶点的。因为这一个边无权重的图,所以只是一个搜索问题。用广度优先搜索就可以解决这个问题。

你可能感兴趣的:(算法)