java狼羊草过河_狼羊菜过河

思路:用0/1代表所处位置,农夫、狼、羊、菜过河就是0000->1111,一共是16种状态,去掉其中的不可能的状态如0011(羊和菜单独一起)是10种。

可以用图的方式表示:

622923c1bb80908babd9679a690c1849.png

或者用树的方式表示

c27d57ba815bb300d28dd40156d5757a.png

简单代码实现如下:

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 listResult = new ArrayList();

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 + " ");

});

}

}

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值