蚂蚁爬杆

来源:互联网 发布:安卓内录软件 编辑:程序博客网 时间:2024/04/27 20:57

1. 问题

有一根27厘米长的细木杆,在第3厘米,7厘米,11厘米,17厘米,23厘米这五个位置上各有一只蚂蚁,木杆很细,不能同时通过两只蚂蚁,开始时,蚂蚁的头朝向左还是右是任意的,它们只会朝前走或掉头,但不会后退,只有当任意两只蚂蚁相遇后,蚂蚁会同时掉头朝反方向走,假设蚂蚁们每秒钟可以走1厘米的距离。

问题1:所有蚂蚁都离开木杆的最短时间和最长时间。

问题2:第i只蚂蚁,什么时候走出木杆?

问题3:问蚂蚁一共碰撞多少次?

问题4:哪只蚂蚁碰撞次数最多?

问题5:两人A(速度为a),B(速度为b)在一直路上相向而行。在A,B距离为s的时候,A放出一个鸽子C(速度为c),C飞到B后,立即掉头飞向A,遇到A再掉头飞向B……就这样在AB之间飞来飞去,直到AB相遇。这期间鸽子共飞行路程为多少?

问题6:轮船(速度为a)在长江(速度为b)里逆流而上行驶。某个时刻,从船上掉下一个救生圈到水中。一个小时后,船员才发现这一情况,于是掉头去找。问什么时候轮船才可以找到这个救生圈?

2. 分析与求解

简单分析不难发现,当两只蚂蚁碰相遇后各自掉头往反方向走,但是可以“看作”是两只蚂蚁相遇后,擦肩而过。

问题1:因为碰撞可以“看作”蚂蚁擦肩而过,因此不用考虑蚂蚁碰撞的问题。可得所有蚂蚁都从离它近的端点离开木杆所用时间最短,从离它远的那端离开所需时间最长。

参考代码如下:

voidCalcTime(double Length,double *XPos,int AntNum,double Speed,double&Min,double &Max)

{

      double TotalTime =Length/Speed;

      double currentMax=0;

      double currentMin=0;

      Max = Min = 0;

      for (int i=0;i < AntNum;i++)

      {

             currentMax = (XPos[i] >(Length/2) ? XPos[i]:(Length-XPos[i]))/Speed;

             Max = Max < currentMax ?currentMax:Max;

             currentMin = TotalTime -currentMax;

             Min = Min < currentMin ?currentMin:Min;

      }

}

问题2:每次碰撞并不会减少或增加向左(右)移动蚂蚁的数量。

不妨假设每只蚂蚁出发时都背着一袋“粮食”,每次碰撞时两只蚂蚁交换粮食,朝相反的方向移动。粮食和蚂蚁的移动速度和时间相同,则第i只蚂蚁移动的距离跟它离开木杆时背的粮食移动的距离一样,因此问题转化为求第i只蚂蚁离开木杆时背的“粮食”的初始位置。

设初始时有M只蚂蚁向右移动,N-M只蚂蚁向左移动,则杆上左边N-M只蚂蚁从左边离开木杆,右边M只蚂蚁从右边离开木杆。

(1) i N - M,则第i只蚂蚁从木杆左端离开。简单分析后不难发现第i只蚂蚁离开木杆时背的“粮食”为第i只向右移动蚂蚁的“粮食”,因此我们只需找到第i只初始时向左移动蚂蚁的位置,它距离左端的距离就是第i只蚂蚁走的路程li,离开木杆时间为li/speed。

(2) i > N – M,则第i只蚂蚁从木杆右端离开。简单分析后可知第i只蚂蚁离开木杆时背的“粮食”为第M-N+i只蚂蚁背的“粮食”。因此我们只需找到第M-N+i只初始时向右移动蚂蚁的位置,它距离右端的距离就是第i只蚂蚁走的路程li,离开木杆时间为li/speed。

为什么从左端的离开的第i只蚂蚁背着初始时第i只向左运动的蚂蚁的粮食?因为初始时向左运动的蚂蚁,其背的粮食必然从左端落下(碰撞不敢边粮食的运动方向),显然有初始时第i只向左爬行的蚂蚁背的粮食会在初始时第i+1只向左爬行的蚂蚁背的粮食从左端离开之前离开,因此有从左端的离开的第i只蚂蚁背着初始时第i只向左运动的蚂蚁的粮食。

问题3:蚂蚁的碰撞可以“看作”擦肩而过,因此碰撞次数跟擦肩而过的次数是相同的。所有蚂蚁的擦肩而过次数等于刚开始时在它前进方向上与它前进相反的蚂蚁的个数。只需统计一个方向上的所有蚂蚁擦肩而过的次数即可。

问题4:扩展第三个问题中的解答思路。假设第i只蚂蚁最终从左边离开木杆,而开始时刻其左边有r只向右走的蚂蚁,则它至少要朝左边碰撞r次才能把左边的蚂蚁全撞成向左的状态(包括直接相撞和间接相撞)。若第i只蚂蚁开始时向左,则共要碰2r次,否则为2r+1次。

问题5:A与B相向而行,速度为a+b,则相遇时两者想走的时间为s/(a+b),因此有鸽子飞行的时间为c* s/(a+b)。

问题6:逆流时船在长江的速度a-b,救生圈的速度b,船顺流时在长江中的速度a+b,则找到救生圈的时间t = (a-b+b) / (a+b-b) = 1h。


参考:编程之美——蚂蚁爬杆

0 0
原创粉丝点击