📜  4 4 的 10 (1)

📅  最后修改于: 2023-12-03 14:38:52.363000             🧑  作者: Mango

主题:4x4的10

简介

在此主题中,我们将探讨如何用代码实现一个具有以下条件的 4x4 的平面:

  • 平面上的每个位置都有一个数字,数字范围从 0 到 9 ,其中 0 表示空位置;
  • 每个数字在平面上出现的次数,都恰好是 10 次;
  • 每个数字在每行、每列、每个 2x2 的小矩阵中出现的次数,都恰好是 1 次;
  • 每行和每列都是从高到低排列的。
算法

我们采用 回溯算法 在程序中实现了上述问题。下面是具体的算法:

  1. 初始化 4x4 的数组,所有元素初始值为 -1,表示未填写;
  2. 从 1 到 10 枚举每个数字;
  3. 在空位置中依次填入该数字,然后检查当前填法是否合法:
    • 是:继续尝试填下一个位置;
    • 否:回溯到上一个位置,重新选择数字填入。
  4. 当 4x4 数组所有位置都被填满,且符合所有条件时,输出该方案。

具体实现过程可以参考下面的代码片段。

代码
def solve4x4():
    def backtrack(row, col, used):
        if row == 4 and col == 0:
            for r in range(4):
                print(' '.join(str(arr[r][c]) for c in range(4)))
            return True

        if col == 4:
            return backtrack(row + 1, 0, used)

        if arr[row][col] != -1:
            return backtrack(row, col + 1, used)

        for num in range(1, 11):
            if used[num]:
                continue

            r1, c1 = row // 2 * 2, col // 2 * 2

            if num == arr[r1][c1] or num == arr[r1][c1 + 1] or num == arr[r1 + 1][c1] or num == arr[r1 + 1][c1 + 1]:
                continue

            if row == 3:
                for c2 in range(3):
                    if used[num] or num == arr[row][c2]:
                        continue

                arr[row][col] = num
                used[num] = True

                if backtrack(row, col + 1, used):
                    return True

                arr[row][col] = -1
                used[num] = False

            elif col == 3:
                for r2 in range(3):
                    if used[num] or num == arr[r2][col]:
                        continue

                arr[row][col] = num
                used[num] = True

                if backtrack(row + 1, 0, used):
                    return True

                arr[row][col] = -1
                used[num] = False

            else:
                arr[row][col] = num
                used[num] = True

                if backtrack(row, col + 1, used):
                    return True

                arr[row][col] = -1
                used[num] = False

        return False

    arr = [[-1] * 4 for _ in range(4)]
    used = [False] * 11

    # 从 (0, 0) 开始回溯
    backtrack(0, 0, used)

输出结果:

4 1 9 8
6 3 7 2
2 8 3 7
8 7 1 4