华为机试真题Java 实现【羊、狼、农夫过河】【2022.11 Q4】

题目描述

羊、狼、农夫都在岸边,当羊的数量小于狼的数量时,狼会攻击羊,农夫则会损失羊。农夫有一艘容量固定的船,能够承载固定数量的动物。

要求求出不损失羊情况下将全部羊和狼运到对岸需要的最小次数。只计算农夫去对岸的次数,回程时农夫不会运送羊和狼。

备注:农夫在或农夫离开后羊的数量大于狼的数量时狼不会攻击羊。

农夫自身不占用船的容量。

输入描述

第一行输入为M,N,X, 分别代表羊的数量,狼的数量,小船的容量。

输出描述

输出不损失羊情况下将全部羊和狼运到对岸需要的最小次数。

(若无法满足条件则输出0)

用例

示例1:

输入:

5 3 3

输出:

3

说明: 第一次运2只狼 第二次运3只羊 第三次运2只羊和1只狼

示例2:

输入:

5 4 1

输出:

0

说明:

如果找不到不损失羊的运送方案,输出0

个人解法

不保证通过率

public class Main {
    public static int minTimes;//记录最小次数
    /**
     * 如需打印每种过河成功的过程 将isShow设为true
     */
    public static boolean isShow = false;//是否打印过程

    public static void main(String[] args) throws IOException {
        // 处理输入
        String[] input = new BufferedReader(new InputStreamReader(System.in)).readLine().split(" ");
        int M = Integer.parseInt(input[0]), N = Integer.parseInt(input[1]), X = Integer.parseInt(input[2]);
        minTimes = (M + N) * X;
        // 表示已运输到对岸的羊、狼个数
        int m_temp = 0;
        int n_temp = 0;
        //加了个HashMap用来记录下过河成功所经历的每次过程中运了多少只羊与狼
        transport(M, N, X, m_temp, n_temp, 0, new HashMap<>());
        if (minTimes == (M + N) * X) {
            System.out.println(0);//从未成功过
        } else {
            System.out.println(minTimes);
        }

    }

    // m0, n0 分别表示剩余的羊、狼个数, x为船容量
    // m1, n1 分别表示运输到对岸的羊、狼个数,times为次数
    public static void transport(int m0, int n0, int x, int m1, int n1, int times, HashMap<Integer, int[]> map) {
        //若可以一次性运走,结束了,注意等于号。。。
        if (x >= m0 + n0) {
            if (times + 1 < minTimes) {
                minTimes = times + 1;
            }
            map.put(times + 1, new int[]{m0, n0});
            if (isShow) {
                for (int i = 1; i <= times + 1; i++) {
                    System.out.print(Arrays.toString(map.get(i)));
                }
                System.out.print("\ttimes:" + (times + 1) + "\n");
            }
            return;
        }
        //尝试运一部分狼一部分羊
        //要上船的羊数量不可以超过岸上数量、也不可以超过船的容量
        for (int i = 0; i <= Math.min(m0, x); i++) {
            //要上船的狼的数量不可以超过岸上数量、也不可以超过船装了羊后的剩余的容量
            for (int j = 0; j <= Math.min(x - i, n0); j++) {
                //不可以不运
                if (i + j == 0) {
                    continue;
                }
                //船离岸后,原来这岸,要么没有羊,要么羊比狼多,才可以运;对岸也要检查,不考虑回程带动物
                if ((m0 - i == 0 || m0 - i > n0 - j) && (m1 + i == 0 || m1 + i > n1 + j)) {
                    //运一次
                    map.put(times + 1, new int[]{i, j});
                    transport(m0 - i, n0 - j, x, m1 + i, n1 + j, times + 1, map);
                }
            }
        }
    }
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值