黑马程序员技术交流社区

标题: 过河问题 [打印本页]

作者: #→_→    时间: 2015-8-16 10:34
标题: 过河问题
  1. import java.util.ArrayList;
  2. /*
  3. * 有一条河,一支船,岸上有一对父母,两个儿子,两个女儿,一个主人一只狗,都要过河,可船只能坐两个人,狗也算。
  4. * 父亲母亲主人会划船,如果父亲走了,母亲会打儿子,母亲走了,父亲会打女儿,主人走了,狗咬人。   问8个人怎样平安过河?
  5. */
  6. public class CopyOfRiverCross {
  7.         public static void main(String[] args) {
  8.                 ArrayList<String> river = new ArrayList<String>();// 河这边
  9.                 ArrayList<String> cross = new ArrayList<String>();// 对岸
  10.                 ArrayList<String> boat = new ArrayList<String>();// 船只
  11.                 river.add("父亲");
  12.                 river.add("狗");
  13.                 river.add("主人");
  14.                 river.add("儿子");
  15.                 river.add("女儿");
  16.                 river.add("女儿2");
  17.                 river.add("儿子2");
  18.                 river.add("母亲");
  19.                 while (true) {
  20.                         group(river, boat,cross);
  21.                         System.out.print(boat+"坐船过去------");
  22.                         land(cross, boat);
  23.                         if (river.isEmpty()) {
  24.                                 System.out.println("--------------------都过去了");
  25.                                 break;
  26.                         }
  27.                         getBack(cross, boat,river);
  28.                         System.out.print(boat+"坐船回来-----");
  29.                         land(river, boat);
  30.                         System.out.println(river+"还没过去");
  31.                 }
  32.         }

  33.         // 上岸
  34.         public static void land(ArrayList<String> land, ArrayList<String> boat) {
  35.                 land.addAll(boat);
  36.                 boat.clear();
  37.         }

  38.         // 返回
  39.         public static void getBack(ArrayList<String> cross, ArrayList<String> boat,ArrayList<String> river) {
  40.                 ArrayList<String> temp = new ArrayList<String>();
  41.                 ArrayList<String> temp2 = new ArrayList<String>();
  42.                 boolean b = true;
  43.                 for (int i = 0; i < cross.size(); i++) {
  44.                         boat.add(cross.get(i));
  45.                         temp.addAll(cross);
  46.                         temp.removeAll(boat);
  47.                         temp2.addAll(boat);
  48.                         temp2.addAll(river);
  49.                         if (isSafe(temp)&isSafe(temp2) & isSail(boat)) {
  50.                                 if (isSafe(temp)) {
  51.                                         cross.removeAll(boat);
  52.                                         b = false;
  53.                                         break;
  54.                                 } else {
  55.                                         boat.clear();
  56.                                         temp.clear();
  57.                                 }
  58.                         } else {
  59.                                 boat.clear();
  60.                                 temp2.clear();
  61.                         }
  62.                 }
  63.                 if(b){
  64.                         group(cross,boat,river);
  65.                 }
  66.         }

  67.         // 遍历上船的所有组合方式,找出可以开船的方案并上船
  68.         public static void group(ArrayList<String> river, ArrayList<String> boat,ArrayList<String> cross) {
  69.                 ArrayList<String> temp = new ArrayList<String>();
  70.                 ArrayList<String> temp2 = new ArrayList<String>();
  71.                 for (int i = 0; i < river.size(); i++) {
  72.                         for (int n = 0; n < i; n++) {
  73.                                 boat.add(river.get(n));
  74.                                 boat.add(river.get(i));
  75.                                 temp.addAll(boat);
  76.                                 temp.addAll(cross);
  77.                                 temp2.addAll(river);
  78.                                 temp2.removeAll(boat);
  79.                                 if (isSafe(temp)&isSafe(temp2) & isSail(boat)) {
  80.                                         river.removeAll(boat);
  81.                                         break;
  82.                                 } else {
  83.                                         boat.clear();
  84.                                         temp.clear();
  85.                                 }
  86.                         }
  87.                         if (isSafe(boat) & isSail(boat)) {
  88.                                 break;
  89.                         } else {
  90.                                 boat.clear();
  91.                         }
  92.                 }
  93.         }

  94.         // 判断是否安全
  95.         public static boolean isSafe(ArrayList<String> list) {
  96.                 if (!list.contains("父亲")&list.contains("母亲") & (list.contains("儿子")|list.contains("儿子2"))||
  97.                         !list.contains("母亲")&list.contains("父亲") & (list.contains("女儿")|list.contains("女儿2"))||
  98.                         !list.contains("主人") & list.contains("狗")&(list.contains("父亲")|list.contains("母亲")|
  99.                         list.contains("儿子")|list.contains("儿子2")|list.contains("女儿"))) {
  100.                         return false;
  101.                 }
  102.                 return true;
  103.         }

  104.         // 判断是否能开船
  105.         public static boolean isSail(ArrayList<String> list) {
  106.                 if (list.contains("父亲") || list.contains("母亲") || list.contains("主人")) {
  107.                         return true;
  108.                 }
  109.                 return false;
  110.         }
  111. }
复制代码


作者: #→_→    时间: 2015-8-16 10:53
本帖最后由 #→_→ 于 2015-8-16 17:51 编辑


把添加元素的顺序打乱,有时候可能会影响到效率,不过还没有验证是否8个元素随机排列无死循环,到时候用Map集合for循环试一下

作者: #→_→    时间: 2015-8-16 17:55
过河类的都是一个思路,条件的判断和元素的遍历,主要就是这2点,在条件的限制下,尽量是多人过河少人回的原则,这类问题的解决也就是这样,不难
作者: 帅帅loyal    时间: 2015-8-16 19:28
这是哪里的题,好变态的说
作者: #→_→    时间: 2015-8-16 20:45
帅帅loyal 发表于 2015-8-16 19:28
这是哪里的题,好变态的说

这类问题的核心就是判断和对集合的元素的遍历,for循环或者while循环或者递归,至少最简单的解法是这样,比遍历文件夹简单多了,你仔细看一遍就会解类似这样的过河的题目了,&和|的和集合,包含的知识点比较少的
作者: pengbeilin    时间: 2015-8-16 21:15
基础题里面的?
作者: #→_→    时间: 2015-8-16 22:24
本帖最后由 #→_→ 于 2015-8-16 22:26 编辑
pengbeilin 发表于 2015-8-16 21:15
基础题里面的?

都是些基础,不要看有这么多,其实就逻辑符,集合,遍历这些,视频里面都会详细讲的知识点
作者: pengbeilin    时间: 2015-8-16 22:31
之前我的是 人和狗猫鱼过何比较简单
作者: iamzk    时间: 2015-8-16 23:05
很好,经典问题
作者: keviner    时间: 2015-8-16 23:17
这个要学习啊
作者: 流水王朝    时间: 2015-8-16 23:37
这个有意思啊
作者: 阮文江    时间: 2015-8-16 23:57
看着好多啊,不过貌似里面的东西不是非常难,还可以理解
作者: #→_→    时间: 2015-8-17 09:48
pengbeilin 发表于 2015-8-16 22:31
之前我的是 人和狗猫鱼过何比较简单

把判断条件改一改,就是一样的原理了
作者: #→_→    时间: 2015-8-17 09:52
阮文江 发表于 2015-8-16 23:57
看着好多啊,不过貌似里面的东西不是非常难,还可以理解

这代码写完还没有优化,看着就比较多,比如可以把开头的while循环换成递归,过河和返回可以写出一个方法共用,
作者: lh5484826    时间: 2015-8-17 12:32
脑袋有点乱。
作者: #→_→    时间: 2015-8-17 21:39
lh5484826 发表于 2015-8-17 12:32
脑袋有点乱。

我代码刚刚写完还没优化就发了
但其实你从下面看回头就懂了,最下面是条件判断,往上分别是过河与返回的方式,最上面就是集合...
作者: 小黑与小白    时间: 2015-8-17 22:12
代码看得好晕啊!!!
作者: 樱花飘过    时间: 2015-8-17 22:30
脑子不够用了,好难
作者: 风华正茂    时间: 2015-8-18 12:41
学习一下
作者: 王盟    时间: 2015-8-18 15:15
有意思的题目,谢楼主。
作者: michael_wlq    时间: 2015-10-8 22:26
代码好长,还是先理清楚思路吧
作者: #→_→    时间: 2015-10-12 11:35
michael_wlq 发表于 2015-10-8 22:26
代码好长,还是先理清楚思路吧

思路大概就是这样了,集合添加元素,判断,不过还没有优化过代码,不过简单的逻辑就只能是这样子啦
作者: 三川草民    时间: 2015-10-12 12:40
这种问题碰到好几个了




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