鬼魂算法
2012-09-23 12:31 ggzwtj 阅读(4032) 评论(15) 编辑 收藏 举报这个方法的名字是从一个大学同学那里得来的。算法本身非常简单,但是这个名字太酷了,所以决定写下来。
题目一:
一个管子里有N个球,它们都在以1M/S的速度(向左或向右)移动,在两个球发生碰撞时,各自掉头并且速度不变,问:多长时间之后N个球全部落地?
相信很多泡过论坛的人这个题目不只见过一次,而解决方法也很简单。为了方便下面进一步的说明,这里赘述一下:
如果换个描述的方法:两个球在相遇的时候,他们并没有发生碰撞而是互相穿越而过(就像两个鬼魂相遇时一样),但是他们的编号互换了。显然,这种描述和题目中的描述是等价的。在这种描述下问题就很好解决了,球与球之间并没有发生碰撞,它沿着它开始的方向移动到对应的尽头便落下,算出所有球中的最大值便是所有球落下的时间。
题目二:
描述同题目一,问:时间T时,求I的位置?
这个问题把题目一往前稍微提了一点点,因为这时候要考虑碰撞了(不然编号什么的都乱了)。这里想一下:
a、其他球的碰撞重要吗?
b、相同方向的球可能相遇吗?
为了更直观的看问题,这里画一个图:
其中白色的球向右,黑色的球向左,标号为i的白球是我们要计算的,现在再来看上面的两个问题。其他球发生碰撞的时候,对球I来说是没有关系的,因为如擦掉球的颜色,在任何碰撞之后整体的情况对I球来说和擦身而过是相同的效果。相同方向的球因为速度相同,永远也不可能相撞。但是,这里要考察的是I球的位置,所有I球的碰撞是需要考虑的。那么问题的解决方法便出来了:
a、忽略其他球之间的碰撞,只考虑I球和其他球的碰撞。
b、每个位置的球只可能和I球碰撞一次,因为碰撞之后方向变为同向。
到这里就差不多了,那么来看下碰撞的规律吧:
根据上面的a、b两条,那么总是白球和黑球相撞,而每次相撞的时间点就是这两个球之间的距离/2。显然随着碰撞时间递增,所以可以依次计算每次碰撞的时间直到满足时间,当然也可以用二分。
------------------------------------------
欢迎拍砖。