一道九宫格算法面试题

前言

一前公司同事把此题放在群里,求大家帮忙解答。

《一道九宫格算法面试题》

因为没有其他条件和说明。我的第一印象就是:方格里应该填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;
}

打印结果只有一组:
《一道九宫格算法面试题》

    原文作者:九宫格问题
    原文地址: https://blog.csdn.net/a10615/article/details/52188190
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞