泥巴麒麟的BLOG

shenAwesome@hotmail.com 纵不能,将醉做生涯,休拘束

  BlogJava :: 首页 :: 联系 :: 聚合  :: 管理
  195 Posts :: 2 Stories :: 80 Comments :: 0 Trackbacks
古老的题目:2个水壶, 一个5升,一个6升。问如何用这2个测量出3升水
一个面向对象的算法程序如下:



结果如下

succeeded: fill a, a->b  (0/5),  fill a, a->b  (4/6), drop b, a->b  (0/4),  fill a, a->b  (3/6),
succeeded: fill a, a->b  (0/5),  fill a, a->b  (4/6), drop b, a->b  (0/4),  fill a, a->b  (3/6), a->b  (3/6),
succeeded:fill b, b->a (5/1), drop a, b->a (1/0), fill b, b->a (5/2), drop a, b->a (2/0), fill b, b->a (5/3),
succeeded:fill b, b->a (5/1), drop a, b->a (1/0), fill b, b->a (5/2), drop a, b->a (2/0), fill b, b->a (5/3), b->a (5/3),

所以是4个解,这算法就是广度遍历,压栈。

还有一个思路,可用逆推
有用的事实:
  1 如果一个壶是非空非满,则另外一个壶必是空或满。
  2 空和满之间转换没难度,思考时可以理解空就是满
  3 记住3是目的。所以3不能参与运算。
设5升壶为a,6升壶为b
则最后的可能

一 a 有3升
   1. b 0升  则说明前一步是 b->a,之前的水是 1/2 或 2/1 对照上述事实,可见此选择不可能。
   2. b 6 升 则说明前一步是 a->b,之前是  5/4 ,ok, 4 只可能为5-1,6-2,加法全部不可能。得到1则很容易。

二 b 有3升
    1. a 0  升 则说明前一步是 a->b
    2. a 5  升 则说明前一步是 b->a

从纯数学的角度来说这个问题是如何用有限的数字组合出最后的数字。这样会大大简化程序。
如果按照逆推的思路,相信也可以写出算法(感觉可以用递归),而且应该速度会快很多。


其实猜出来很容易,但是要找出统一规律则有些难度。我本来以为会有很多解,但我的算法只算出来4个,应该是准确的。




posted on 2008-11-12 06:38 泥巴麒麟 阅读(102) 评论(0)  编辑  收藏

只有注册用户登录后才能发表评论。


网站导航: