思路:用0/1代表所处位置,农夫、狼、羊、菜过河就是0000->1111,一共是16种状态,去掉其中的不可能的状态如0011(羊和菜单独一起)是10种。
可以用图的方式表示:
或者用树的方式表示
简单代码实现如下:
package algorithm;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.IntStream;
public class CrossRiver {
static int farmer = 0, wolf = 1, sheep = 2, cabbage = 3;
static int start = 0, end = 15;
static List<String> listResult = new ArrayList<String>();
static boolean cross(int[] conds) {
for (int curr : conds) {
// 跳过已发生的状态
if (listResult.contains("" + curr)) continue;
listResult.add("" + curr);
// 如已找到解,则返回
if (curr == end) return true;
// 找到可以转化的状态
int[] nexts = IntStream.range(0, 16).filter(item -> isValid(curr, item)).toArray();
// 如所有状态都无解,则移除当前步骤
if (!cross(nexts)) listResult.remove("" + curr);
// 如已找到解,则直接返回
if(listResult.contains("" + end)) return true;
}
return false;
}
// 是否满足条件
static boolean isValid(int curr, int next) {
if (position(curr, farmer) == position(next, farmer)) {
return false;
} // 农夫没过河
if (position(next, wolf) == position(next, sheep) & position(next, farmer) != position(next, wolf)) {
return false;
} // 狼羊单独
if (position(next, sheep) == position(next, cabbage) & position(next, farmer) != position(next, sheep)) {
return false;
} // 羊菜单独
if (position(curr, farmer) != position(curr, wolf) & position(curr, wolf) != position(next, wolf)) {
return false;
} // 狼不在身边不能带着过河
if (position(curr, farmer) != position(curr, sheep) & position(curr, sheep) != position(next, sheep)) {
return false;
} // 羊不在身边不能带着过河
if (position(curr, farmer) != position(curr, cabbage) & position(curr, cabbage) != position(next, cabbage)) {
return false;
} // 菜不在身边不能带着过河
if (Math.abs(curr - next) != 8 & Math.abs(curr - next) != 9 & Math.abs(curr - next) != 10
& Math.abs(curr - next) != 12) {
return false;
} // 超载或其他情况
return true;
}
// 获取位置
static char position(int i, int pos) {
String tmp = Integer.toBinaryString(i);
tmp = ("0000" + tmp).substring(tmp.length());
return tmp.charAt(pos);
}
static void print() {
String out = "";
String east = "东岸:";
String west = "西岸:";
if (position(15, farmer) == 0) {
east += "农夫 ";
} else {
west += "农夫 ";
}
if (position(15, wolf) == 0) {
east += "狼 ";
} else {
west += "狼 ";
}
if (position(15, sheep) == 0) {
east += "羊 ";
} else {
west += "羊 ";
}
if (position(15, cabbage) == 0) {
east += "菜 ";
} else {
west += "菜 ";
}
out += east + "\n" + west + "\n";
System.out.println(out);
}
public static void main(String[] args) {
//把农夫、狼、羊、菜过河看作从0000 -> 1111的变化
int[] conditions = { start };
cross(conditions);
listResult.stream().forEach(item -> {
String tmp = Integer.toBinaryString(Integer.valueOf(item));
tmp = ("0000" + tmp).substring(tmp.length());
System.out.print(tmp + " ");
});
}
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。