欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

所有可能幻方解法使用回溯

程序员文章站 2022-05-18 20:52:28
...

幻方 指N^2 格子放入所有1-N^2 的数子 使得格子水平列、垂直行或对角线数字和相同

求得所有可能 

使用回溯法

public class Magiques {
    int max, sumNum, n;
    public List<String> desQuassez(int n) {
        List<String> res = new ArrayList<>();
        if (n < 1) return res;
        int[][] board = new int[n][n];
        this.n = n;
        max =  n * n;
        sumNum = (max + 1) * n / 2;
        boolean[] allUsed = new boolean[n * n];
        int[] colSum = new int[n];
        int[] rowSum = new int[n];
        int forwardSum = 0;
        int inverseSum = 0;
        recurse(res, 0, board, allUsed, colSum, rowSum, forwardSum, inverseSum);
        return res;
    }
    /**
     * 递归求解
     * @param res 结果
     * @param fixN 第N个格子
     * @param board 填充数字的格子
     * @param allUsed 使用过的数字  allUsed[i] = true 指 第i个数字已被使用
     * @param colSum 列的和
     * @param rowSum 行的和
     * @param forward 正斜线的和
     * @param inverseSum 逆斜线的和
     */
    private void recurse(List<String> res,int fixN, int[][] board, boolean[] allUsed, int[] colSum, int[] rowSum, int forwardSum, int inverseSum) {
        int row = fixN / n;
        int col = fixN % n;
        if (col > 0 && row == n - 1 && colSum[col - 1] != sumNum) return;
        if (fixN >= n && col == 0 && rowSum[row - 1] != sumNum) return;
        if (row == n - 1 && col > 0 && inverseSum != sumNum) return;
        if (fixN == max) {
            if (forwardSum != sumNum) return;
            res.add(Arrays.deepToString(board));
            return;
        }
        for (int i = 1; i <= max; i++) {
            if (allUsed[i - 1]) continue;
            allUsed[i - 1] = true;
            board[row][col] = i;
            colSum[col] += i;
            rowSum[row] += i;
            if (col == row) forwardSum += i;
            if (col + row == n - 1) inverseSum += i;
            recurse(res, fixN + 1, board, allUsed, colSum, rowSum, forwardSum, inverseSum);
            if (col == row) forwardSum -= i;
            if (col == n - row - 1) inverseSum -= i;
            colSum[col] -= i;
            rowSum[row] -= i;
            board[row][col] = 0;
            allUsed[i - 1] = false;
        }
    }
    public static void main(String[] args) {
        Magiques testInstance = new Magiques();
        List<String> res = testInstance.desQuassez(4);
        res.stream().forEach(o -> System.out.println(o));
        System.out.println(res.size());
    }
}

 

相关标签: recursion