三妖怪,三和尚过河问题(美图2017线下笔试题)

//三个妖怪和三个和尚过河,当一边的和尚数小于妖怪数,则和尚被吃,找出过河方案

package cn.edu.wtu.test;

public class Test { final static int MOSTER = 3; // 妖怪数 final static int MONK = 3; // 和尚数 private static int path[] = new int[20]; // 保存河左边的妖怪和和尚数(妖怪*10+和尚) /** * 过河 * * @param goMoster 过河的妖怪数 * @param goMonk 过河的和尚数 * @param L_moster 过河前左边妖怪数 * @param L_monk 过河前左边和尚数 * @param cnt 存放path下标 * @return */ public static boolean goTo(int goMoster, int goMonk, int L_moster, int L_monk, int cnt) { // 过河后 左边妖怪,和尚数 L_moster -= goMoster; L_monk -= goMonk; // 全部过河,输出过河方法,负数表示返回 if (L_moster == 0 && L_monk == 0) { for (int i = 0; path[i] != 0; ++i) { int moster = path[i] / 10 - path[i + 1] / 10; int monk = path[i] % 10 - path[i + 1] % 10; System.out.println("第" + i + "次:" + moster + "妖怪 " + monk + "和尚过河"); } return true; } // 过河后 判断左岸是否满足条件 if (L_moster > L_monk && L_monk != 0) { return false; } // 得到右岸妖怪,和尚数 int R_moster = MOSTER - L_moster; int R_monk = MONK - L_monk; // 判断右岸妖怪和尚是否满足条件 if (R_moster > R_monk && R_monk != 0) { return false; } int tmp = L_moster * 10 + L_monk; // 防止重复,出现死循环 for (int i = 1; i < cnt; i += 2) { if (tmp == path[i]) { return false; } } path[cnt++] = tmp; // 返回左岸 for (int i = 0; i <= R_moster && i <= 1; ++i) { for (int j = 0; j <= 1 && j <= R_monk; ++j) { if (i + j > 0) { if (goBack(i, j, R_moster, R_monk, cnt)) { return true; } } } } return false; } public static boolean goBack(int backMoster, int backMonk, int R_moster, int R_monk, int cnt) { R_moster -= backMoster; R_monk -= backMonk; if (R_moster > R_monk && R_monk != 0) { return false; } int L_moster = MOSTER - R_moster; int L_monk = MONK - R_monk; if (L_moster > L_monk && L_monk != 0) { return false; } int tmp = L_moster * 10 + L_monk; for (int i = 0; i < cnt; i += 2) { if (tmp == path[i]) { return false; } } path[cnt++] = tmp; // 过河 for (int i = 0; i <= L_moster && i <= 2; ++i) { for (int j = 0; j <= L_monk && j <= 2; ++j) { if (i + j > 0 && goTo(i, 2 - i, L_moster, L_monk, cnt)) { return true; } } } return false; } public static void main(String[] args) { int i; int cnt = 0; path[cnt++] = MOSTER * 10 + MONK; // 初始状态,左岸3和尚3妖怪 for (i = 0; i <= 2; ++i) { for (int j = 0; j <= 2; ++j) { if (i + j > 0 && goTo(i, j, MOSTER, MONK, cnt)) { return; } } } if (i > 2) { System.out.println("无解"); } } }

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值