黑马程序员技术交流社区
标题:
狗猫鱼过河问题,分享我的代码和思路
[打印本页]
作者:
朦胧色彩
时间:
2015-10-14 12:50
标题:
狗猫鱼过河问题,分享我的代码和思路
本帖最后由 朦胧色彩 于 2015-10-21 13:47 编辑
一位老农带着猫、狗、鱼过河,河边有一条船,每次老农只能带一只动物过河。当老农不和猫狗鱼在一起时,狗会咬猫,猫会吃鱼,当老农和猫狗鱼在一起时,则不会发生这种问题。编程解决猫狗鱼过河问题。
import java.util.*;
/**
* 思路:使用递归。在此岸枚举动物过河,判断剩下是否能够共存,如果过河了,判断对岸的是否可以共存,两边轮流枚举,知道对岸的能够共存为此。
* @author 朦胧色彩
*/
public class Test {
private static int go = -1; // 记住过河的动物
private static int back = -1; // 记录回头的动物
private static String animal[] = {"狗", "猫", "鱼"};
public static void main(String[] args) {
ArrayList<Integer> here = new ArrayList<Integer>();
ArrayList<Integer> there = new ArrayList<Integer>();
System.out.println("0代表狗,1代表猫,2代表鱼"+"\n");
// 初始化此岸的动物有哪些
for(int i = 0;i < 3; i++)
here.add(i);
// 一开始是过河
crossRiver(here, there, true, -1);
there.add(here.get(0));
here.remove(0);
System.out.println("最后农夫和猫过河");
System.out.println("此岸:"+here+"\t彼岸:"+there);
}
/*
* a b 代表此岸,彼岸或者(彼岸,此岸),具体由where决定
* where 代表的是过河和回来 true是此岸去彼岸,false是彼岸回此岸
* type 是记录上一次过河或者回来的是哪种动物
*/
public static void crossRiver(ArrayList<Integer> a, ArrayList<Integer> b, boolean where, int type)
{
if(where) // 过
System.out.println("此岸:"+a+"\t彼岸:"+b);
else // 回
System.out.println("此岸:"+b+"\t彼岸:"+a);
for(int i = 0; i < a.size() ; i++)
{
if(type != a.get(i))
{
int temp = a.get(i);
//System.out.println(temp + " " + i);
a.remove(i);
if(!isOk(a) && a.size() > 1){
a.add(temp);
Collections.sort(a);
}
else
{
// 如果是过河的,那么用go记录住这次是谁过的,如果过了对岸,发现不能共存的话,就不能是它回头了,避免死循环
if(where){
go = temp;
System.out.println("农夫和"+animal[temp]+"过河");
}
// 回头的,back记录住谁回头了
else{
back = temp;
System.out.println("农夫和"+animal[temp]+"回河");
}
b.add(temp);
Collections.sort(b);
// 如果对岸只有一种动物,那么此岸还要继续
if(b.size() == 1)
{
//System.out.println(a+" "+b+"-1");
crossRiver(a, b, true, back);
}
// 当该岸已经有两种动物了,那就要判断是否能够共存,这里是不能共存的操作
else if(!isOk(b))
{
//System.out.println(b+" "+a+"-2");
if(where) // 如果是刚过去的,且目前该岸不能共存的话,那就回一种动物到对岸,并且该种动物不能是go
crossRiver(b, a, false, go);
else // 如果是刚回来的,且目前该岸不能共存的话,那就过一种动物到对岸,并且该种动物不能是back
crossRiver(b, a, true, back);
}
else
{
//System.out.println(a+" - " + b + "="+back);
crossRiver(a, b, true, back);
}
}
}
}
}
// 判断农夫所在的岸边是否能够共存
public static boolean isOk(ArrayList<Integer> arr)
{
int sum = 0;
if(arr.size() < 2)
return false;
for(int i = 0; i < arr.size(); i++)
sum += arr.get(i);
// 狗和猫相加是1,猫和鱼相加是3,都是不能共存的
if(sum == 1 || sum == 3)
return false;
return true;
}
}
复制代码
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2