A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 闫镜湾 中级黑马   /  2014-5-23 14:50  /  2740 人查看  /  15 人回复  /   1 人收藏 转载请遵从CC协议 禁止商业使用本文

有一根27厘米的细木杆,在第3厘米、7厘米、11厘米、17厘米、23厘米这五个位置上各有一只蚂蚁。
木杆很细,不能同时通过一只蚂蚁。开始 时,蚂蚁的头朝左还是朝右是任意的,它们只会朝前走或调头,
但不会后退。当任意两只蚂蚁碰头时,两只蚂蚁会同时调头朝反方向走。假设蚂蚁们每秒钟可以走一厘米的距离。
编写程序,求所有蚂蚁都离开木杆 的最小时间和最大时间。

15 个回复

倒序浏览
分析:题目中的蚂蚁只可能相遇在整数点,不可以相遇在其它点,比如3.5cm处之类的,也就是可以让每只蚂蚁走 1秒,然后
* 查看是否有相遇的即可.
*
* 这样我的程序实现思路就是,初始化5只蚂蚁,让每只蚂蚁走1秒,然后看是否有相遇的,如果有则做相应处理.当每只蚂蚁都
* 走出木杆时,我就记录当前时间.这样就可以得到当前状态情况下,需要多久可以走出木杆,然后遍历所有状态则可以得到所胡
* 可能.
回复 使用道具 举报
这个题,在ACM中貌似见过。。用排序,好像吧。。
回复 使用道具 举报
这么难啊。。。
回复 使用道具 举报
坐等代码 求长见识~~~
回复 使用道具 举报
来围观一下,果断发现看完就懵了...
回复 使用道具 举报
屈_zi 中级黑马 2014-5-24 11:54:08
7#
好难啊~~
回复 使用道具 举报
屈_zi 中级黑马 2014-5-24 16:39:54
8#
先上代码
  1. /**
  2. * 模拟蚂蚁运行的木棒,木棒长度为l,有l个点,每个点上的蚂蚁数量初始化为0
  3. * @author Administrator
  4. *
  5. */
  6. class L{
  7.         static int l = 27;
  8.         static int[] point = new int[l + 1];
  9.         static{
  10.                 for(int i = 0; i < l + 1; i++){
  11.                         point[i] = 0;
  12.                 }
  13.         }
  14. }

  15. /**
  16. * 蚂蚁类,有运动方向,初始位置,以及运动的方法及Thread的run方法,
  17. * run方法模拟蚂蚁的实际运动
  18. * @author Administrator
  19. *
  20. */
  21. class Ant extends Thread{
  22.         private static int[] F = {1, -1};//1向右,-1向左
  23.         private int f;
  24.         private int place;
  25.         private String name = "";
  26.         private static Object obj = new Object();
  27.         int time = 0;
  28.        
  29.         //蚂蚁编号
  30.         static int num = 0;
  31.        
  32.         //初始化蚂蚁的名称、运动方向(0向右,1向左)和位置
  33.         Ant(String name, int i, int place){
  34.        
  35.                
  36.                 this.name = name;
  37.                 this.f = F[i];
  38.                 this.place = place;
  39.                 if(L.point[place] != 0){
  40.                         System.out.println("Error");
  41.                 }
  42.                 L.point[place] = 1;
  43.         }
  44.         //蚂蚁运动
  45.         public void run(){       
  46.                 //获取当前蚂蚁的编号
  47.                 int c = num++;
  48.                
  49.                 while(place > 0 || place < L.l){
  50.                         try {Thread.sleep(600);} catch (InterruptedException e) {}       
  51.                         //如果两只蚂蚁相遇,则调转方向,相遇设计成如果L上的某个点的蚂蚁数量大于1,
  52.                         //为了保证这段代码能被安全的执行,将1s的sleep时间分成两个部分,使线程有足够的时间完成判断和调转方向
  53.                         if(L.point[place] > 1){
  54.                                 f = -f;
  55.                                 System.out.println(name + " turn foward in " + place);                               
  56.                         }       
  57.                         try {Thread.sleep(300);} catch (InterruptedException e) {}       
  58.                        
  59.                         place += f;       
  60.                         //如果已经抵达0点或者第27点,那么就离开,即设置0点和27点上的蚂蚁个数为0
  61.                         //以及1和26点上的蚂蚁个数为0
  62.                         if(place <= 0 || place >= L.l){               
  63.                                 if(place <= 0){
  64.                                         L.point[place + 1] = 0;
  65.                                 }
  66.                                 if(place >= L.l){
  67.                                         L.point[L.l - 1] = 0;
  68.                                 }
  69.                                 //从1和26到0和27也需要1s的时间
  70.                                 time++;
  71.                                 break;
  72.                         }       
  73.                         //加锁避免同时操作place,尤其两只蚂蚁到同一个点相遇的时
  74.                         synchronized (obj) {
  75.                                 //蚂蚁到place点,则数量加1
  76.                                 L.point[place]++;       
  77.                                 //蚂蚁所在的前一个位置的蚂蚁数量编程0
  78.                                 L.point[place - f] = 0;               
  79.                         }
  80.                         //时间加1
  81.                         time++;                                       
  82.                 }               
  83.                 System.out.println(name + " Time:" + time);
  84.                 //保存结果到SearchTime中
  85.                 SearchTime.runTime[c % 5] = time;
  86.         }
  87. }

  88. /**
  89. * 搜索线程,可以搜索指定蚂蚁运动方向组合的所有蚂蚁都离开的时间
  90. * @author Administrator
  91. *
  92. */
  93. class SearchTime extends Thread{
  94.         private int tag;
  95.         static int[] runTime = new int[5];
  96.         //搜索运动方向为tag指示的情况时的所有蚂蚁都离开L的时间
  97.         SearchTime(int tag){
  98.                 this.tag = tag;
  99.         }
  100.        
  101.         public void run(){
  102.                 System.out.println("Start tag = " + tag);
  103.                 //5只蚂蚁,方向一共有32种可能,因此tag应当是小于32大于0的数,tag的二进制
  104.                 //每一个位代表一只蚂蚁的运动方向
  105.                 if(tag >= 32 || tag < 0){
  106.                         System.out.println("error");                       
  107.                 }else{                       
  108.                         Ant ant1 = new Ant("Ant1", tag & 1, 3);
  109.                         Ant ant2 = new Ant("Ant2", (tag & 2) >> 1, 7);
  110.                         Ant ant3 = new Ant("Ant3", (tag & 4) >> 2, 11);
  111.                         Ant ant4 = new Ant("Ant4", (tag & 8) >> 3, 17);
  112.                         Ant ant5 = new Ant("Ant5", (tag & 16) >> 4, 23);       
  113.                        
  114.                         ant1.start();
  115.                         ant2.start();
  116.                         ant3.start();
  117.                         ant4.start();
  118.                         ant5.start();
  119.                 }
  120.         }
  121. }
  122. public class BaiduEm {

  123.         public static void main(String[] args) throws InterruptedException {
  124.                 int[] result = new int[32];
  125.                 for(int i = 0; i < 32; i++){
  126.                         SearchTime st = new SearchTime(i);
  127.                         st.start();
  128.                         try {Thread.sleep(30000);} catch (InterruptedException e) {}       
  129.                         result[i] = findMax(SearchTime.runTime);
  130.                         System.out.println("Max:" + result[i]);
  131.                 }
  132.                 System.out.println("所有蚂蚁都离开的最短时间:" + findMin(result) + "s" );
  133.                 System.out.println("所有蚂蚁都离开的最长时间:" + findMax(result) + "s" );
  134.         }
  135.        
  136.         /*
  137.          * 寻找一个数组中的最大值
  138.          */
  139.         public static int findMax(int[] array){
  140.                 int max = array[0];
  141.                 for(int i = 0; i < array.length; i++){
  142.                         max = array[i] > max ? array[i] : max;
  143.                 }
  144.                 return max;
  145.         }
  146.        
  147.         /*
  148.          * 寻找一个数组中的最小值
  149.          */
  150.         public static int findMin(int[] array){
  151.                 int min = array[0];
  152.                 for(int i = 0; i < array.length; i++){
  153.                         min = array[i] < min ? array[i] : min;
  154.                 }
  155.                 return min;
  156.         }

  157. }
复制代码



回复 使用道具 举报
屈_zi 中级黑马 2014-5-24 16:42:25
9#
运行结果摘要:
Start tag = 29
Ant3 turn foward in 9
Ant2 turn foward in 9
Ant1 Time:3
Ant4 turn foward in 12
Ant3 turn foward in 12
Ant5 turn foward in 15
Ant4 turn foward in 15
Ant2 Time:11
Ant3 Time:17
Ant5 Time:20
Ant4 Time:23
Max:23
Start tag = 30
Ant2 turn foward in 5
Ant1 turn foward in 5
Ant2 turn foward in 7
Ant3 turn foward in 7
Ant1 Time:7
Ant4 turn foward in 10
Ant3 turn foward in 10
Ant4 turn foward in 13
Ant5 turn foward in 13
Ant2 Time:11
Ant3 Time:17
Ant4 Time:23
Ant5 Time:24
Max:24
Start tag = 31
Ant1 Time:3
Ant2 Time:7
Ant3 Time:11
Ant4 Time:17
Ant5 Time:23
Max:23
所有蚂蚁都离开的最短时间:11s
所有蚂蚁都离开的最长时间:24s


这题的重点应该不是看你编程能力,而是搜索的思想,最小值很容易确定,最大值是3到27的时间,也就是第一只蚂蚁到第27点的时间,最小值容易证明,最大值是这个应该也可以证

点评

好赞的赶脚  发表于 2014-5-25 01:12
回复 使用道具 举报 1 0
果断学习下 。。。。。
回复 使用道具 举报
赞一个!!!
回复 使用道具 举报
这道题很有意思,惠存了,等有时间了思考下。
回复 使用道具 举报
长长见识,看看各位大神的回答!嘿嘿嘿
回复 使用道具 举报
百度就是百度,好难
回复 使用道具 举报
学习了!!!
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马