思维拓展:用java实现巧妙过桥问题

问题:小明一家过一座桥,过桥的时候是黑夜,所以必须有灯。现在小明过桥要 2 分钟,小明 的弟弟要 5 分钟,小明的爸爸要 6 分钟,小明的妈妈要 9 分钟,小明的爷爷要 13 分钟。每次 此桥最多可以过两人,而过桥的速度根据过桥最慢者而定,而且灯在点燃后 40 分钟就会熄灭。 问小明一家如何过桥时间最短?

代码如下:

public class demo {
    static int index;                            //过桥临时方案的数组下标
    static int size = 64;
    static int N = 5;
    static int mintime = 40;                    //最小过桥时间总和,初始值30
    static int[] transit = new int[size];        //进行下标中转的数组
    static int program[] = new int[size];         //最短时间内过桥的方案;
    //    static int time[] = {1, 3, 6, 8, 12};         //每个人过桥所需要的时间;
    static int time[] = {2, 5, 6, 9, 13};         //每个人过桥所需要的时间;
    /*
     * 将人员编号:小明 location[0],弟弟location[1],
     * 爸爸location[2],妈妈location[3],爷爷location[4] 每个人的当前位置:0--在桥左边, 1--在桥右边
     */
    static int location[] = new int[N];

    /*
     * 参数说明:notPass:未过桥人数;usedtime:当前已用时间;Direction:过桥方向,1--向右,0--向左
     */
    public static void Find(int notPass, int usedtime, int Direction) {
        if (notPass == 0) {                 //所有人已经过桥,更新最少时间及方案
            mintime = usedtime;
            for (int i = 0; i < size && transit[i] >= 0; i++) {
                program[i] = transit[i];
            }
        } else if (Direction == 1) {         //过桥方向向右,从桥左侧选出两人过桥
            for (int i = 0; i < N; i++) {
                if (location[i] == 0 && (usedtime + time[i]) < mintime) {
                    transit[index++] = i;
                    location[i] = 1;
                    for (int j = 0; j < N; j++) {
                        int TmpMax = (time[i] > time[j] ? time[i] : time[j]);
                        if (location[j] == 0 && (usedtime + TmpMax) < mintime) {
                            transit[index++] = j;
                            location[j] = 1;
                            Find((notPass - 2), (usedtime + TmpMax), 0);
                            location[j] = 0;
                            transit[--index] = -1;
                        }
                    }
                    location[i] = 0;
                    transit[--index] = -1;
                }
            }
        } else { //过桥方向向左,从桥右侧选出一个人回来送灯
            for (int j = 0; j < N; j++) {
                if (location[j] == 1 && usedtime + time[j] < mintime) {
                    transit[index++] = j;
                    location[j] = 0;
                    Find(notPass + 1, usedtime + time[j], 1);
                    location[j] = 1;
                    transit[--index] = -1;
                }
            }
        }
    }

    public static void main(String[] args) {
        String s1 = "", s2 = "", s3 = "";
        for (int i = 0; i < size; i++) {
            program[i] = -1;
            transit[i] = -1;                //初始方案内容为负值,避免和人员标号冲突
        }
        Find(N, 0, 1); // 查找最佳方案
        System.out.println("最短过桥时间为:" + mintime);        //输出最短过桥时间
        System.out.println("最佳过桥组合为:");                // 输出最佳过桥组合
        for (int i = 0; i < size && program[i] >= 0; i += 3) {
            switch (program[i]) {
                case 0:
                    s1 = "小明";
                    break;
                case 1:
                    s1 = "弟弟";
                    break;
                case 2:
                    s1 = "爸爸";
                    break;
                case 3:
                    s1 = "妈妈";
                    break;
                case 4:
                    s1 = "爷爷";
                    break;
            }
            switch (program[i + 1]) {
                case 0:
                    s2 = "小明";
                    break;
                case 1:
                    s2 = "弟弟";
                    break;
                case 2:
                    s2 = "爸爸";
                    break;
                case 3:
                    s2 = "妈妈";
                    break;
                case 4:
                    s2 = "爷爷";
                    break;
            }
            switch (program[i + 2]) {
                case 0:
                    s3 = "小明";
                    break;
                case 1:
                    s3 = "弟弟";
                    break;
                case 2:
                    s3 = "爸爸";
                    break;
                case 3:
                    s3 = "妈妈";
                    break;
                case 4:
                    s3 = "爷爷";
                    break;
                case -1:
                    s3 = "没人";
                    break;
            }

            System.out.println(s1 + "和" + s2 + "一道过桥," + s3 + "再回来");
        }
    }
}

执行结果如下:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

数据知道

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值