黑马程序员技术交流社区

标题: 关于农民带猫狗鱼过河的问题 [打印本页]

作者: lwy0319    时间: 2014-3-10 12:40
标题: 关于农民带猫狗鱼过河的问题
本帖最后由 lwy0319 于 2014-3-22 00:17 编辑

大家好,我是来自海淀区的新人,刚刚通过云九班报名的基础测试,希望还能赶上与大家做同学的机会
我做基础测试耽误时间最久的就是最后一题
题目如下:
一位老农带着猫、狗、鱼过河,河边有一条船,每次老农只能带一只动物过河。当老农不和猫狗鱼在一起时,狗会咬猫,猫会吃鱼,当老农和猫狗鱼在一起时,则不会发生这种问题。
PS:这个是道经典的逻辑题,所以大家可能很早就有接触了
我个人感觉这题的编码难点跟逻辑推断难点是一致的:怎么去想到带猫从对岸回来/怎么让程序自己做出这个选择
我自己花了5个写了个很繁琐的算法,也在网上看了一些答案,但是目前找到解答难点的
基本上不约而同的讲把猫带回或者把动物带回当作是一种已经存在方案然后备选,而不是让程序自己递推出来
我自己也没做到,但是我还是感觉一段程序,自己加入的逻辑思路的痕迹越少越好
附件是我的代码,希望大家能给予我指点

农夫带猫狗鱼.rar

3.75 KB, 下载次数: 1429


作者: 刘望望    时间: 2014-3-10 22:56
楼主最后虽然得到了正确的结果,但是最后输出结果不够清晰,而且程序执行的每一步都是跟着你的思想在进行,没有一点程序自己的选择,这是我写的,可以交流一下

Test10.rar

1.34 KB, 下载次数: 1767


作者: lwy0319    时间: 2014-3-11 11:02
谢谢你,比我写得简练多了,其实我还是尽量让系统自己判断的,只不过用了循环,恨不得每一步都进行了循环并在内部进行判断,现在看来还是挺繁琐的,我为了让他们正常的按组内的索引编号循环下去,每次不得不复位直到找到正确答案才真正进行remove和add操作,你的比我的优化了很多,多谢指教了
作者: lwy0319    时间: 2014-3-13 23:29
标题: RE: 关于农民带猫狗鱼过河的问题
呃。。怎么结帖。。没找到哪儿能改成已解决

作者: ℡╭ァ拚命り呼    时间: 2014-3-15 19:30
都是大神呀,我就写了几行代码哈。。。
作者: ‍杨博    时间: 2014-6-8 20:38
想了半天,没搞清思路。还是参考下大神的答案吧
作者: ‍杨博    时间: 2014-6-8 20:43
刘望望童鞋确实思路清晰,领教了

作者: 阿小活    时间: 2014-6-16 00:51
经典的题目...
作者: 八零、玖羚    时间: 2014-7-27 14:40
思路清晰就好
作者: 你好吗    时间: 2014-7-31 17:05
这也是我的基础测试题最后一题,没有思路,正在膜拜大神的杰作
作者: wfaly    时间: 2014-8-19 08:22
谢谢,楼主分享...
作者: 笑轻轻    时间: 2014-8-24 13:04
我也在想这问题 这题目看着简单 想想要做好 还是有一点难度的
作者: 孙小亚    时间: 2014-8-24 20:09
刘望望 发表于 2014-3-10 22:56
楼主最后虽然得到了正确的结果,但是最后输出结果不够清晰,而且程序执行的每一步都是跟着你的思想在进行, ...

厉害!!!
作者: xhbxhb    时间: 2014-9-1 23:14
真心不错
作者: 言钟钟    时间: 2014-9-3 16:00
刘望望 发表于 2014-3-10 22:56
楼主最后虽然得到了正确的结果,但是最后输出结果不够清晰,而且程序执行的每一步都是跟着你的思想在进行, ...

public boolean isSafe(List<String> list)
        {
                boolean b = true;
               
                //如果某一边没有人,猫单独和其他动物在一起,则不和谐
                if(list.size() > 1 && list.contains("cat") && !list.contains("person"))
                {
                        b = false;
                }
               
                return b;
        }
这个函数为什么要boolean b = true;  直接return true,不可以吗?  有什么特别的?
作者: mengzi987    时间: 2014-10-19 18:02
刘望望 发表于 2014-3-10 22:56
楼主最后虽然得到了正确的结果,但是最后输出结果不够清晰,而且程序执行的每一步都是跟着你的思想在进行, ...

你好!在吗?/我在网上看到你的一份关于农夫过河的问题!有个问题想请教你
作者: mengzi987    时间: 2014-10-19 21:50
lwy0319 发表于 2014-3-11 11:02
谢谢你,比我写得简练多了,其实我还是尽量让系统自己判断的,只不过用了循环,恨不得每一步都进行了循环并 ...

楼上的好像有点问题啊

作者: P李勇    时间: 2015-4-3 01:16
学习啊了,厉害!
作者: 小小瓶盖❤    时间: 2015-7-27 00:37
  1. package com.itheima;

  2. import java.util.ArrayList;
  3. import java.util.List;
  4. import java.util.Random;

  5. /**
  6. * 10、 一位老农带着猫、狗、鱼过河,河边有一条船,每次老农只能带一只动物过河。当老农不和猫狗鱼在一起时, 狗会咬猫,猫会吃鱼,当老农和猫狗鱼在一起时,
  7. * 则不会发生这种问题。编程解决猫狗鱼过河问题。
  8. *
  9. * 分析:
  10. *         假设动物和老农都在左岸,要到达右岸
  11. *                 第一步:老农带着猫到达右岸
  12. *                 第二步:老农一个返回左岸
  13. *                 第三步:老农带着狗或者鱼到达右岸
  14. *                 第四步:老农带着猫返回左岸
  15. *                 第五步:老农带着非猫的动物到达右岸
  16. *                 第六步:老农一个人返回左岸
  17. *                 第七步:老农带着猫到达右岸
  18. *                 过河完成!
  19. *
  20. * 把整个过河问题分为从左岸到右岸,从右岸到左岸这两个动作问题。
  21. * 老农从左岸到右岸,必须带着动物,否则没有任何意义,并且该动物不能为上次从右岸返回到左岸的动物。老农从右岸到左岸,
  22. * 如果可以不带动物,则不带,效率高,否则必须带一个动物返回左岸,并且该动物不能为上次从左岸到达右岸的动物。
  23. *
  24. * 采用过程追溯法来是实现过河问题,不满足条件追溯回原状态,知道满足条件为止。
  25. *
  26. * @author liuxiangyun
  27. *
  28. */
  29. public class Test10 {
  30.         List<String> leftBank = new ArrayList<String>();// 左岸
  31.         List<String> rightBank = new ArrayList<String>();// 右岸

  32.         public static void main(String args[]) {
  33.                 new Test10().crossRiver();
  34.         }

  35.         public Test10() {
  36.                 // 初始化数据
  37.                 leftBank.add("person");
  38.                 leftBank.add("fish");
  39.                 leftBank.add("cat");
  40.                 leftBank.add("dog");
  41.         }

  42.         // 过河
  43.         public void crossRiver() {
  44.                 boolean isAtLeftBank = true;// 老农是否在左边
  45.                 String lastToLeftAnl = "";// 上一个到左边去的动物,默认没有,用""表示
  46.                 String lastToRightAnl = "";// 上一个到右边去的动物,默认没有,用""表示
  47.                 while (leftBank.size() > 0) {
  48.                         //从左岸到右岸
  49.                         if (isAtLeftBank) {
  50.                                 lastToRightAnl = toRight(lastToLeftAnl);
  51.                                 System.out.println("老农带着{" + lastToRightAnl + "}到达右岸");
  52.                                 isAtLeftBank = false;
  53.                         //从右岸到左岸
  54.                         } else {
  55.                                 lastToLeftAnl = toLeft(lastToRightAnl);
  56.                                 if (lastToLeftAnl == "")
  57.                                         System.out.println("老农一个人回到左岸");
  58.                                 else
  59.                                         System.out.println("老农带着{" + lastToLeftAnl + "}到达左岸");
  60.                                 isAtLeftBank = true;
  61.                         }
  62.                 }
  63.                 System.out.println("老农和动物全部过河!");
  64.         }

  65.         /**
  66.          * 从左岸到右岸,老农必须携带一个动物,否则没有任何意义,并且要保证左右岸不出现安全问题
  67.          *
  68.          * @param lastToLeftAniaml
  69.          *            上一个到左岸去的动物,没有则用""表示
  70.          * @return 返回要携带的动物
  71.          */
  72.         public String toRight(String lastToLeftAniaml) {
  73.                 boolean flag = true;
  74.                 String animal = null;
  75.                 while (flag) {
  76.                         leftBank.remove("person");
  77.                         animal = leftBank.get(new Random().nextInt(leftBank.size()));// 随机获取一个动物
  78.                         leftBank.remove(animal);
  79.                         rightBank.add("person");
  80.                         rightBank.add(animal);
  81.                         if (isSafe() && (animal != lastToLeftAniaml)) {// 不是上一个去左边的动物,并且不产生和谐问题
  82.                                 flag = false;
  83.                         } else {
  84.                                 rightBank.remove("person");
  85.                                 rightBank.remove(animal);
  86.                                 leftBank.add("person");
  87.                                 leftBank.add(animal);
  88.                         }
  89.                 }
  90.                 return animal;
  91.         }

  92.         /**
  93.          * 从左岸到右岸,老农独自返回,如果没有产生安全问题,他就独自返回,否则必须携带一个动物返回左岸,并且也要保证不产生安全问题。
  94.          *
  95.          * @param lastToRightAniaml
  96.          *            上一个到达右岸的动物
  97.          * @return 返回要携带的动物,没有则返回""
  98.          */
  99.         public String toLeft(String lastToRightAniaml) {
  100.                 String animal = null;
  101.                 rightBank.remove("person");
  102.                 leftBank.add("person");
  103.                 if (isSafe()) {
  104.                         return animal = "";
  105.                 } else {
  106.                         leftBank.remove("person");
  107.                         rightBank.add("person");
  108.                         boolean flag = true;
  109.                         while (flag) {
  110.                                 rightBank.remove("person");
  111.                                 animal = rightBank.get(new Random().nextInt(rightBank.size()));// 随机获取一个动物
  112.                                 rightBank.remove(animal);
  113.                                 leftBank.add("person");
  114.                                 leftBank.add(animal);
  115.                                 if (isSafe() && (animal != lastToRightAniaml)) {// 不是上一个去右边的动物,并且不产生和谐问题
  116.                                         flag = false;
  117.                                 } else {
  118.                                         leftBank.remove("person");
  119.                                         leftBank.remove(animal);
  120.                                         rightBank.add("person");
  121.                                         rightBank.add(animal);
  122.                                 }
  123.                         }
  124.                 }
  125.                 return animal;
  126.         }

  127.         // 判断左右岸是否存在安全问题
  128.         public boolean isSafe() {
  129.                 boolean leftBankIsSafe = true;
  130.                 boolean rightBankIsSafe = true;
  131.                 // 岸上没有老农,有猫且有狗或者鱼就存在安全问题
  132.                 if (!leftBank.contains("person") && leftBank.contains("cat")
  133.                                 && leftBank.size() > 1)
  134.                         leftBankIsSafe = false;
  135.                 if (!rightBank.contains("person") && rightBank.contains("cat")
  136.                                 && rightBank.size() > 1)
  137.                         rightBankIsSafe = false;
  138.                 return leftBankIsSafe && rightBankIsSafe;
  139.         }
  140. }
复制代码

作者: 鹏飞    时间: 2015-8-12 14:37
牛呀!!!!!
作者: cuijinghao    时间: 2015-9-18 13:03
依然不知道过河是什么意思
作者: 边情2015    时间: 2015-11-13 00:34
不用那么长代码的,亲们。
这晚我刚刚写的,讨论学习。

  1. import java.util.LinkedList;

  2. public class Ferry {

  3.         public static void main(String[] args) {
  4.                 LinkedList<String> here = new LinkedList<String>();
  5.                 LinkedList<String> there = new LinkedList<String>();
  6.                 String cat = "猫";
  7.                 String dog = "狗";
  8.                 String fish = "鱼";
  9.                 int count = 0;
  10.                 here.add(cat);
  11.                 here.add(dog);
  12.                 here.add(fish);
  13.                 while(there.size()<3){
  14.                         System.out.println("----第"+(++count)+"次摆渡开始----");
  15.                         String boat = null;
  16.                         while(true){
  17.                                 boat = here.removeFirst();
  18.                                 if(isNice(here)){
  19.                                         there.addLast(boat);
  20.                                         System.out.println("老农正把("+boat+")送往河对面....");
  21.                                         break;
  22.                                 }
  23.                                 here.addLast(boat);
  24.                         }
  25.                         if(!isNice(there)&&there.size()<3){
  26.                                         boat = there.removeFirst();
  27.                                         System.out.println("并把("+boat+")往回送....");
  28.                                         here.addLast(boat);
  29.                                 }
  30.                         System.out.println("河这面:"+here);
  31.                         System.out.println("河对面:"+there);
  32.                 }
  33.         }
  34.         public static boolean isNice(LinkedList<String> li){
  35.                 if(li.contains("猫")&&li.contains("鱼"))
  36.                         return false;
  37.                 else if(li.contains("狗")&&li.contains("猫"))
  38.                         return false;
  39.                 else
  40.                         return true;
  41.         }
  42. }
复制代码





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