1. 程式人生 > >一道九宮格演算法面試題

一道九宮格演算法面試題

前言

一前公司同事把此題放在群裡,求大家幫忙解答。

這裡寫圖片描述

因為沒有其他條件和說明。我的第一印象就是:方格里應該填1~9整數中剩下的1~8,且不能重複。於是拿著筆進行了一通計算。。。後來發現無解。

接著,就想裡面的算術運算子(+、-、×、÷),不按優先順序,直接按先後順序來計算,如:a - b × c,當做(a - b) × c 來運算。最後得到如下結果:

5   8   9
7   6   4
3   2   1

為了鍛鍊下自己的演算法能力,後來用Java寫了份程式碼來測試:

public static void main(String[] args) {
    nineBlockBox();
}

private
static void nineBlockBox() { List<int[]> result = compute(); printf("列印結果:\n"); for (int i = 0; i < result.size(); i++) { printf("第%d組結果:\n", i+1); int count = 0; for (int a : result.get(i)) { printf(a + "\t"); if (++count == 3) { printf("\n"
); count = 0; } } } } private static List<int[]> compute() { // 九宮格位置: // 0 1 2 // 3 4 5 // 6 7 8 // 條件 // ① (nb[0] + nb[1]) - 9 = 4 // ② (nb[3] - nb[4]) * nb[5] = 4 // ③ (nb[6] + nb[7]) - nb[8] = 4 // ④ (nb[0] + nb[3]) / nb[6] = 4
// ⑤ (nb[1] - nb[4]) * nb[7] = 4 // ⑥ ( 9 - nb[5]) - nb[8] = 4 List<int[]> list = new ArrayList<>(); int[] nb = new int[9]; for (int i = 1; i <= 9; i++) { // 初始化數值 initArr(nb); if (!isNumValid(nb, i)) { continue; } nb[0] = i; // ① (nb[0] + nb[1]) - 9 = 4 int temp = 4 + 9 - nb[0]; if (!isNumValid(nb, temp)) { nb[0] = 0; continue; } nb[1] = temp; for (int j = 1; j <= 9; j++) { if (!isNumValid(nb, j)) { continue; } nb[5] = j; // ⑥ ( 9 - nb[5]) - nb[8] = 4 temp = 9 - nb[5] - 4; if (!isNumValid(nb, temp)) { nb[5] = 0; continue; } nb[8] = temp; for (int k = 1; k <= 9; k++) { if (!isNumValid(nb, k)) { continue; } nb[3] = k; // ② (nb[3] - nb[4]) * nb[5] = 4 // 4 = 1 * 4 = 2 * 2 temp = nb[3] - 4 / nb[5]; if (!isNumValid(nb, temp)) { nb[3] = 0; continue; } nb[4] = temp; for (int m = 1; m <= 9; m++) { if (!isNumValid(nb, m)) { continue; } nb[6] = m; // ③ (nb[6] + nb[7]) - nb[8] = 4 temp = 4 + nb[8] - nb[6]; if (!isNumValid(nb, temp)) { nb[6] = 0; continue; } nb[7] = temp; // ④ (nb[0] + nb[3]) / nb[6] = 4 // ⑤ (nb[1] - nb[4]) * nb[7] = 4 if (((nb[0] + nb[3]) / nb[6] == 4) && ((nb[1] - nb[4]) * nb[7] == 4)) { int[] result = new int[nb.length]; System.arraycopy(nb, 0, result, 0, nb.length); list.add(result); } nb[6] = nb[7] = 0; } nb[3] = nb[4] = 0; } nb[5] = nb[8] = 0; } } return list; } private static void initArr(int[] arr) { Arrays.fill(arr, 0); arr[2] = 9; } private static boolean isNumValid(final int[] arr, final int num) { if (num < 1 || num > 9) { return false; } for (int a : arr) { if (a == num) { return false; } } return true; }

列印結果:
這裡寫圖片描述

後來百度得知這是一道騰訊校招筆試題。

正題

題目:

用0~100的整數填入以下方格中,使填入後的運算結果,滿足下圖所示的條件。求出所有解。
這裡寫圖片描述

個人解答過程:

把每一個條件進行,並把相關的條件進行整合分析,最後根據整合結果寫程式碼。條件的分析在程式碼中(為了方便閱讀理解,沒有作優化,如i, j, k臨時變數完全可以去掉)

private static List<int[]> compute_100() {
    //  九宮格位置:
    //  0   1   2
    //  3   4   5
    //  6   7   8

    // 條件
    // ① a[0] + a[1] -  9   = 4
    // ② a[3] - a[4] * a[5] = 4
    // ③ a[6] + a[7] - a[8] = 4
    // ④ a[0] + a[3] / a[6] = 4
    // ⑤ a[1] - a[4] * a[7] = 4
    // ⑥  9   - a[5] - a[8] = 4

    /*
        分析
        ①:a[0] + a[1] = 13      -->     a[0]∈[0,13], a[1]∈[0,13]    ......⑦
        ②:a[3] >= 4
        ④:a[0] <= 4, a[6] != 0  +⑦-->   a[0]∈[0,4],a[1]∈[9,13]       ......⑧
        ⑤:a[1] >= 4             +⑧-->   (a[4] * a[7])∈[5,9],即:a[4]∈[1,9],a[7]∈[1,9]
        ⑥:a[5] + a[8] = 5       -->     a[5]∈[0,5], a[8]∈[0,5]

     */

    List<int[]> list = new ArrayList<>();

    int[] a = new int[9];
    a[2] = 9;
    for (int i = 0; i <= 4; i++) {
        a[0] = i;
        a[1] = 13 - i; // ① a[0] + a[1] -  9   = 4

        for (int j = 0; j <= 5; j++) {
            a[5] = j;
            a[8] = 5 - j; // ⑥ 9   - a[5] - a[8] = 4

            for (int k = 1; k <= 9; k++) {
                a[4] = k;
                a[3] = 4 + a[4] * a[5]; // ② nb[3] - nb[4] * nb[5] = 4

                float temp = (a[1] - 4) / a[4]; // ⑤ nb[1] - nb[4] * nb[7] = 4
                // 去小數
                if (a[1] - a[4] * temp != 4f) {
                    continue;
                }
                a[7] = (int)temp;

                a[6] = 4 + a[8] - a[7]; // ③ nb[6] + nb[7] - nb[8] = 4
                if (a[6] != 0) {
                    // 去小數
                    if (a[0] + a[3] * 1f / a[6] == 4f) { // ④ nb[0] + nb[3] / nb[6] = 4
                        int[] result = new int[a.length];
                        System.arraycopy(a, 0, result, 0, a.length);
                        list.add(result);
                    }
                }
            }
        }
    }
    return list;
}

列印結果只有一組:
這裡寫圖片描述