黑马程序员技术交流社区

标题: 狗猫鱼过河问题,分享我的代码和思路 [打印本页]

作者: 朦胧色彩    时间: 2015-10-14 12:50
标题: 狗猫鱼过河问题,分享我的代码和思路
本帖最后由 朦胧色彩 于 2015-10-21 13:47 编辑

一位老农带着猫、狗、鱼过河,河边有一条船,每次老农只能带一只动物过河。当老农不和猫狗鱼在一起时,狗会咬猫,猫会吃鱼,当老农和猫狗鱼在一起时,则不会发生这种问题。编程解决猫狗鱼过河问题。
  1. import java.util.*;

  2. /**
  3. * 思路:使用递归。在此岸枚举动物过河,判断剩下是否能够共存,如果过河了,判断对岸的是否可以共存,两边轮流枚举,知道对岸的能够共存为此。
  4. * @author 朦胧色彩
  5. */

  6. public class Test {  

  7.         private static int go = -1;                // 记住过河的动物
  8.         private static int back = -1;           // 记录回头的动物
  9.         private static String animal[] = {"狗", "猫", "鱼"};

  10.     public static void main(String[] args) {  
  11.   
  12.                 ArrayList<Integer> here = new ArrayList<Integer>();
  13.                 ArrayList<Integer> there = new ArrayList<Integer>();

  14.                 System.out.println("0代表狗,1代表猫,2代表鱼"+"\n");
  15.                 // 初始化此岸的动物有哪些
  16.                 for(int i = 0;i < 3; i++)
  17.                         here.add(i);
  18.                
  19.                 // 一开始是过河
  20.                 crossRiver(here, there, true, -1);
  21.                 there.add(here.get(0));
  22.                 here.remove(0);
  23.                 System.out.println("最后农夫和猫过河");
  24.                 System.out.println("此岸:"+here+"\t彼岸:"+there);
  25.         }

  26.         /*
  27.          * a b 代表此岸,彼岸或者(彼岸,此岸),具体由where决定
  28.          * where 代表的是过河和回来 true是此岸去彼岸,false是彼岸回此岸
  29.          * type 是记录上一次过河或者回来的是哪种动物
  30.          */
  31.         public static void crossRiver(ArrayList<Integer> a, ArrayList<Integer> b, boolean where, int type)
  32.         {
  33.                 if(where) // 过
  34.                         System.out.println("此岸:"+a+"\t彼岸:"+b);
  35.                 else // 回
  36.                         System.out.println("此岸:"+b+"\t彼岸:"+a);

  37.                 for(int i = 0; i < a.size() ; i++)
  38.                 {
  39.                         if(type != a.get(i))
  40.                         {
  41.                                 int temp = a.get(i);
  42.                                 //System.out.println(temp + " " + i);
  43.                                 a.remove(i);
  44.                                 if(!isOk(a) && a.size() > 1){
  45.                                         a.add(temp);
  46.                                         Collections.sort(a);
  47.                                 }
  48.                                 else
  49.                                 {
  50.                                         // 如果是过河的,那么用go记录住这次是谁过的,如果过了对岸,发现不能共存的话,就不能是它回头了,避免死循环
  51.                                         if(where){
  52.                                                 go = temp;
  53.                                                 System.out.println("农夫和"+animal[temp]+"过河");
  54.                                         }
  55.                                         // 回头的,back记录住谁回头了
  56.                                         else{
  57.                                                 back = temp;
  58.                                                 System.out.println("农夫和"+animal[temp]+"回河");
  59.                                         }
  60.                                         b.add(temp);
  61.                                         Collections.sort(b);
  62.                                         // 如果对岸只有一种动物,那么此岸还要继续
  63.                                         if(b.size() == 1)
  64.                                         {
  65.                                                 //System.out.println(a+" "+b+"-1");
  66.                                                 crossRiver(a, b, true, back);
  67.                                         }
  68.                                         // 当该岸已经有两种动物了,那就要判断是否能够共存,这里是不能共存的操作
  69.                                         else if(!isOk(b))
  70.                                         {
  71.                                                 //System.out.println(b+" "+a+"-2");
  72.                                                 if(where) // 如果是刚过去的,且目前该岸不能共存的话,那就回一种动物到对岸,并且该种动物不能是go
  73.                                                         crossRiver(b, a, false, go);        
  74.                                                 else // 如果是刚回来的,且目前该岸不能共存的话,那就过一种动物到对岸,并且该种动物不能是back
  75.                                                         crossRiver(b, a, true, back);
  76.                                         }
  77.                                         else
  78.                                         {
  79.                                                 //System.out.println(a+" - " + b + "="+back);
  80.                                                 crossRiver(a, b, true, back);
  81.                                         }
  82.                                 }
  83.                         }
  84.                 }
  85.         }

  86.         // 判断农夫所在的岸边是否能够共存
  87.         public static boolean isOk(ArrayList<Integer> arr)
  88.         {
  89.                 int sum = 0;
  90.                 if(arr.size() < 2)
  91.                         return false;
  92.                 for(int i = 0; i < arr.size(); i++)
  93.                         sum += arr.get(i);
  94.                 // 狗和猫相加是1,猫和鱼相加是3,都是不能共存的
  95.                 if(sum == 1 || sum == 3)
  96.                         return false;
  97.                 return true;
  98.         }
  99. }  
复制代码







欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2