4.7 蚂蚁爬杆

4.7 蚂蚁爬杆

基本问题 : 有一根27cm的木杆,在第3cm,7cm,11cm,17cm,23cm这5个位置上各有一只蚂蚁,木杆很细不能同时通过两只蚂蚁。开始的时候,蚂蚁的头朝向是随机的,有可能朝右也有可能朝左,他们只会向前走,不会后退,当两只蚂蚁碰头时,两只蚂蚁会掉头同时朝反方向走,假设蚂蚁们每秒钟可以走1cm的距离,编写程序求出所有蚂蚁都离开木杆的最长时间与最短时间。

解法

两只蚂蚁遇见的时候同时掉头,那就可以看作是没有掉头直接穿过对方继续向前进

拓展问题

1 第i个蚂蚁,什么时候走出木杆?

解法:可以看作是每只蚂蚁背了不同重量的粮食,然后碰头之后,将粮食互换,然后掉头。假设有M只蚂蚁向左走,N只蚂蚁向右走,那么最终也将会有M只蚂蚁木杆左边落下,N只蚂蚁从木杆右侧落下.原因很简单,因为每次相遇都掉头,实质上并没有改变朝向左边或者右边的蚂蚁的数量,所以我们想要看第i只蚂蚁什么时候走出木杆,就需要先判断这只蚂蚁的朝向,如果朝向左,就看这个蚂蚁是头向左的第k只蚂蚁,然后看从左边下落第k袋粮食的时间就是蚂蚁下落的时间。

2 如果蚂蚁在一个平面上运动,同样也是碰头后原路返回(这样和弹性碰撞不同,没有相当于两个蚂蚁交换继续前进的本质),问蚂蚁如何走出平面?

解法:感觉有问题,如果蚂蚁正好构成三角形,就会死锁

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

解法:每次两只蚂蚁相遇,蚂蚁就相当于穿过对方继续向前前进,古总的碰撞次数就等于每只蚂蚁穿过蚂蚁的数量。对于头朝向左的蚂蚁,只会穿过在他左边且头朝向右的蚂蚁的数量

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

解法:不要考虑花里胡哨的,直接以时间为基线.

\(c*\frac{s}{a+b}\)

轮船(速度为a)在长江(速度为b)里逆流而上行驶。某一个时刻,从船上落下一个救生圈到水中,一个小时后,船员发现,掉头寻找,问经过多长时间可以找到?

解法:1个小时

// 4.7 蚂蚁爬杆
import java.util.*;
class Test{
	public static void main(String[] args) {
		/**
		基本问题
			有一根27cm的木杆,在第3cm,7cm,11cm,17cm,23cm这5个位置上各有一只蚂蚁,木杆很细
			不能同时通过两只蚂蚁。开始的时候,蚂蚁的头朝向是随机的,有可能朝右也有可能朝左,他们只
			会向前走,不会后退,当两只蚂蚁碰头时,两只蚂蚁会掉头同时朝反方向走,假设蚂蚁们每秒钟可以
			走1cm的距离,编写程序求出所有蚂蚁都离开木杆的最长时间与最短时间。
		> 解法:
			两只蚂蚁遇见的时候同时掉头,那就可以看作是没有掉头直接穿过对方继续向前进
		*/
		/**
		拓展问题
			1 第i个蚂蚁,什么时候走出木杆?
				解法:可以看作是每只蚂蚁背了不同重量的粮食,然后碰头之后,将粮食互换,然后掉头。
					假设有M只蚂蚁向左走,N只蚂蚁向右走,那么最终也将会有M只蚂蚁木杆左边落下,N只蚂蚁从木杆右侧落下
					原因很简单,因为每次相遇都掉头,实质上并没有改变朝向左边或者右边的蚂蚁的数量,所以我们想要看第i只
					蚂蚁什么时候走出木杆,就需要先判断这只蚂蚁的朝向,如果朝向左,就看这个蚂蚁是头向左的第k只蚂蚁,然后看
					从左边下落第k袋粮食的时间就是蚂蚁下落的时间。
			2 如果蚂蚁在一个平面上运动,同样也是碰头后原路返回(这样和弹性碰撞不同,没有相当于两个蚂蚁交换继续前进的本质),问蚂蚁如何走出平面?
				解法:感觉有问题,如果蚂蚁正好构成三角形,就会死锁
			3 问蚂蚁一共会碰撞多少次?
				解法:每次两只蚂蚁相遇,蚂蚁就相当于穿过对方继续向前前进,古总的碰撞次数就等于每只蚂蚁穿过蚂蚁的数量。
					对于头朝向左的蚂蚁,只会穿过在他左边且头朝向右的蚂蚁的数量。
			4 两人A(速度为a),B(速度为b),在一直路上相向而行。在A,B距离s的时候,A放出一个格子C(速度为c),C飞到B之后,立即掉头飞向A,遇到A之后再飞向B。就这样在AB之间飞来飞去,直到AB相遇。问这期间鸽子一共飞了多少路程?
				解法:不要考虑花里胡哨的,直接以时间为基线,$c*\frac{s}{a+b}$
			5 轮船(速度为a)在长江(速度为b)里逆流而上行驶。某一个时刻,从船上落下一个救生圈到水中,一个小时后,船员发现,掉头寻找,问经过多长时间可以找到?
				解法:1个小时
		*/
		int[] left = new int[]{4,3};
		int[] right = new int[]{0,1};
		int[] res = getLastMoment(4,left,right);
		print(res);
		
	}
	public static void print(int[] arr){
		for(int i:arr) System.out.print(i+" ");
		System.out.println();
	}
	/**
	int n : 木杆的长度
	int[] left : 头朝向左的蚂蚁的位置
	int[] ritgh : 头朝向右的蚂蚁的位置
	return int[slow fast]
 	*/
	public static int[] getLastMoment(int n,int[] left,int[] right){
		int slow = Integer.MAX_VALUE;
		int fast = Integer.MIN_VALUE;
		for(int i :left){
			slow = Math.min(i,slow);
			fast = Math.max(i,fast);
		}
		for(int i:right){
			slow = Math.min(n-i,slow);
			fast = Math.max(n-i,fast);
		}
		int[] res = new int[]{slow,fast};
		return res;
	}
}
posted @ 2020-11-26 10:18  BOTAK  阅读(311)  评论(1编辑  收藏  举报