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;
}
}
Saying Less Doing More