九枚硬币翻转问题

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


问题描述:

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

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

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


难点:

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

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值