小朋友呢 发表于 2016-11-5 09:13

java老农过河问题解决

一位老农带着猫、狗、鱼过河,河边有一条船,每次老农只能带一只动物过河。当老农不和猫狗鱼在一起时,狗会咬猫,猫会吃鱼,当老农和猫狗鱼在一起时,则不会发生这种问题。编程解决猫狗鱼过河问题。一开始我看到这个题我还不会做,于是上网 看了下别人怎么做的,发现我好像看不懂,代码太长了,我参照着别人的思路自己写了试试...

解决思路:
        1.定义两个集合来保存两岸的动物
        2.默认都在左岸,右岸的集合为空
        3.定义一个方法监测动物会不会冲突
        4.定义一个变量,来记录老农现在划船划到了哪个岸上,再定义一个变量来存放每一次过河带的动物
        5.如果左岸集合的动物全送走了,就结束

package test;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

public class Test2
{
        public static void main(String[] args)
        {
                ArrayList<String> left = new ArrayList<String>();//定义左岸集合
                ArrayList<String> right = new ArrayList<String>();//定义右岸集合
                left.add("狗");
                left.add("鱼");
                left.add("猫");//把动物先加入到左岸集合中
                String animal=null;//定义一个变量来存放当前要送出去的动物
                int        count=0;                        //定义个变量来存放老农过河的次数,单数为准备去右河岸,双数反之
                Random r =new Random();
                while(!left.isEmpty())
                {
                        count++;//每走一次就+1
                        animal=null;//初始化下一次要送出去的动物                       
                        if(count%2==1)//如果老农要去右岸
                        {
                                do//现在我采用的是随机挑选一个动物去右岸,直到不冲突为止
                                {
                                        animal=left.remove(r.nextInt(left.size()));        //随机挑选一个动物
                                        if(!cmpAnimal(left))
                                        {
                                                left.add(animal);        //如果送出去这个动物有冲突,就把他加回来重新挑选
                                        }
                                } while (!cmpAnimal(left));//如果不为真,就代表冲突了,继续循环,直到不冲突为止
                                System.out.println("老农第"+count+"次,把"+animal+"送到了对岸...");       
                                right.add(animal);                //循环结束后肯定返回的是一个没有冲突的动物                               
                        }else if(count%2==0)//否则就是偶数,代表老农要从河岸回来
                        {       
                                while(!cmpAnimal(right))//这里不用dowhile因为从左岸送过来的至少有一个动物,不用担心冲突
                                {
                                        animal=right.remove(r.nextInt(right.size()));
                                        if(!cmpAnimal(right))
                                        {
                                                right.add(animal);//如果发生冲突了,采用随机的方法挑选一个动物返回到到河对面去
                                        }
                                }
                                if(animal==null)//如果挑选出来的动物等于null表示河岸不存在冲突的地方直接返回去
                                {
                                        System.out.println("老农第"+count+"次,从河岸返回到了河对面...");
                                        continue;//如果没有动物就返回到循环开始
                                }
                                System.out.println("老农第"+count+"次,把"+animal+"送回到了河对面...");//如果说冲突了,就把某个动物带到河对面去..
                                left.add(animal);
                        }               
                }               
        }

        public static boolean cmpAnimal(List<String> list)
        {
                if(list.contains("猫")&&list.contains("鱼")||list.contains("猫")&&list.contains("狗"))
                {
                        return false;                //如果冲突了就返回假
                }       
                return true;//没冲突就返回真
        }
       
}




因为采用的是随机的方法,所以次数可能会变化,反正最小就7次,哈哈:lol

怪兽吃糖果 发表于 2016-12-7 08:02

本帖最后由 怪兽吃糖果 于 2016-12-7 14:14 编辑

楼主我有个建议,可以加个限制:一次来回不运同种动物,这样出来应该都是最小次数了

import java.util.ArrayList;
import java.util.Random;

public class X {

    public static void main(String[] args) throws Exception {
      Random random = new Random();
      ArrayList<String> left = new ArrayList<String>(); //左岸集合
      ArrayList<String> right = new ArrayList<String>(); //右岸集合
      left.add("狗");
      left.add("猫");
      left.add("鱼"); //初始化
      String animal, old = null; //animal运送的动物,old标志,使一次来回不都运同一种动物
      int counts = 0; //次数
      while (!left.isEmpty()) {
            counts++; //一开始次数+1
            animal = null; //运送的动物初始化
            if (counts % 2 == 1) {
               do {
                  if(animal != null)
                        left.add(animal); //如果不符合条件要先把拿出来的动物放回去
                  animal = left.remove(random.nextInt(left.size())); //随机选中一只将要运送的动物
                } while (!coexistence(left) || animal.equals(old)); //选出的动物要使其在岸上可以共存
                right.add(animal); //加入右岸
                old = animal; //标志
                System.out.println("第" + counts + "次" + "把" + animal + "运到右岸");
            } else {
                if (coexistence(right)) {
                  old = null;
                  System.out.println("第" + counts + "次独自返回左岸");;
                  continue;//如果右岸本来就可以共存,直接返回
                } else {
                  do {
                        if(animal != null)
                            right.add(animal);
                        animal = right.remove(random.nextInt(right.size()));
                  } while (animal.equals(old));
                  left.add(animal);
                  old = animal;
                  System.out.println("第" + counts + "次" + "把" + animal + "运回左岸");
                }
            }
      }

    }

    public static boolean coexistence(ArrayList<String> arrayList) {
      if ((arrayList.contains("狗") && arrayList.contains("猫")) || (arrayList.contains("猫") && arrayList.contains("鱼")))
            return false;
      return true;
    }

}

likang 发表于 2016-11-5 11:07

本帖最后由 likang 于 2016-11-5 11:11 编辑

正确的不是把鱼放水里,先把猫弄过去,再把狗抱过去。
狗好像不咬鱼的吗? 好吧我信了, 那不放鱼也行, 我想大家应该都想到了。

olanping 发表于 2016-11-5 09:32

不错,学习了            啊

ffg998 发表于 2016-11-5 09:37

很棒,很不错

sosohappy_htm 发表于 2016-11-5 09:52

学习了,可以{:301_993:}

kojety 发表于 2016-11-5 10:12

不错,不错

13057565289 发表于 2016-11-5 10:33

好牛,,,

小木hwy 发表于 2016-11-5 10:36

支持了啊。!

songtaoshikuang 发表于 2016-11-5 10:46

楼主厉害,谢谢分享,学习了

tkss1111 发表于 2016-11-5 11:41

挺有趣的,学习了。
页: [1] 2 3
查看完整版本: java老农过河问题解决