2017完美世界研發部筆試題_取經

題目概述

師徒四人西天取經,途中必需跨過一座橋,四我的從橋的同一端出發,你得幫助他們到達另外一端,天色很暗而他們只有一支手電筒,一次同時最多能夠有兩我的一塊兒通過橋。而過橋的時候必須持有手電筒,因此就得有人把手電筒帶來帶去,來回橋兩端。手電筒不能用丟的方式來傳遞,四我的的步行速度各不一樣,若兩人同行則以較慢者的速度爲準,大師兄需花1分鐘過橋,二師兄需花2分鐘過橋,三師兄需花5分鐘過橋,師傅需花10分鐘過橋。請問他們最短在多少分鐘內過橋?()
A. 18
B. 17
C. 19
D. 16java

2、思路

一開始直接想到,用最小的那個數來回跑,也就是大師兄來回跑,算出來是19,但是又想了下,以下:
一、大師兄和二師兄過橋,算二師兄的時間也就是2分鐘
二、大師兄獨自拿手電回來 1分鐘
三、三師弟和師傅那手電過橋,算師傅的時間也就是10分鐘
四、二師弟拿手電回來 2分鐘
五、最後大師兄和二師弟過橋 2分鐘
總共17分鐘編程

這裏寫圖片描述

雖然結果出來了,感受有點不實在,這其中的規律是怎樣的呢?有沒有什麼規律解決這相似的問題呢,好比只有三我的過橋呢?二師兄不過橋,結果又是什麼呢?再好比,多一我的過橋呢?多了個白龍馬過橋,白龍馬過橋的時間時6分鐘,結果又是什麼呢?有沒有什麼規律呢,或者說有沒有個公式來計算呢?用編程怎麼解?app

求教大神?先睡了,嘗試下編程解決!oop

3、編程解決

2016年10月7日01:39:55
原本當時寫博客的次日就用編程解決了這個問題的,但是由於種種緣由,尚未時間把代碼貼上來!spa

import java.util.ArrayList;

public class Pilgrimage {

    final static int times[] = { 1, 2, 5, 10 };// 花費時間
    final static String names[] = { "大師兄", "二師兄", "三師兄", "師傅" };// 人物

    public static void main(String[] args) {
        Integer other_bridges[] = { 0, 0, 0, 0 };// 橋另外一邊
        Integer bridges[] = { 1, 1, 1, 1 };// 當前橋這邊 ,1表示存在,0表示不在

        // 開始遞歸
        loop(bridges, other_bridges, 0, new StringBuffer());
    }

    private static void loop(Integer[] bridges, Integer[] other_bridges,
            int time, StringBuffer msg) {
        ArrayList<Integer> positions = new ArrayList<Integer>();// 記錄還在起始端人的下標
        for (int i = 0; i < bridges.length; i++) {
            if (bridges[i] == 1) {
                positions.add(i);// 記錄下標
            }
        }
        int len = positions.size();

        for (int i = 0; i < len - 1; i++) {
            for (int j = i + 1; j < len; j++) { // 循環取結合
                // 記錄狀態
                Integer[] zt_bridges = bridges.clone();
                Integer[] zt_other_bridges = other_bridges.clone();
                int zt_time = time;
                StringBuffer zt_msg = new StringBuffer(msg);

                // 過橋---------
                time += times[positions.get(j)];// 花費時間直接取最大的
                move(bridges, other_bridges, 1, positions.get(i));
                move(bridges, other_bridges, 1, positions.get(j));
                msg.append(" 過橋:" + names[positions.get(i)] + "&"
                        + names[positions.get(j)]);
                // System.out.print(" 過橋:" + names[positions.get(i)] + "_"
                // + names[positions.get(j)]);

                // 回來接人------
                if (isend(other_bridges)) {
                    msg.append(" 總共花費:" + time);
                    System.out.println(msg.toString());
                    // System.out.println(" 總共花費:" + time);
                    return;
                }
                int k = 0;
                for (int ii = 0; ii < other_bridges.length; ii++) {// 選擇最快的回來
                    if (other_bridges[ii] == 1) {
                        k = ii;
                        break;
                    }
                }
                time += times[k];
                move(bridges, other_bridges, 0, k);
                msg.append("  回來:" + names[k]+"  ***  ");
                // System.out.print(" 回來:" + names[k]);

                // 繼續循環遍歷
                loop(bridges.clone(), other_bridges.clone(), time,
                        new StringBuffer(msg));

                // 還原狀態
                bridges = zt_bridges;
                other_bridges = zt_other_bridges;
                time = zt_time;
                msg = zt_msg;
            }
        }
    }

    /**
     * 移動的那我的
     * 
     * @param bridges
     * @param other_bridges
     * @param direction
     *            方向
     * @param position
     */
    private static void move(Integer[] bridges, Integer[] other_bridges,
            int direction, int position) {
        if (direction == 1) {// 往另外一端走
            bridges[position] = 0;
            other_bridges[position] = 1;
        } else {// 回來接人走
            bridges[position] = 1;
            other_bridges[position] = 0;
        }
    }

    // 判斷是否已經結束了
    // 當other_bridges {1,1,1,1}表示結束
    private static boolean isend(Integer[] other_bridges) {
        for (int i : other_bridges) {
            if (i == 0)
                return false;
        }
        return true;
    }

}

運行的結果:
這裏寫圖片描述code

相關文章
相關標籤/搜索