n queens puzzle

N queens puzzle

Math solution

The solution is not unique, this method provide only one of them.
在这里插入图片描述

DFS

用四个数组记录位置可选的状态,每填一个点,其所导致失效的行、列、两个对角线必定是独一无二的,这样就方便在DFS中还原可选状态,比记录点[row][col]更好,因为同一点可能因多个点的填入被设为无效。

  • 对角线 \ : row - col = -(n-1) ~ n-1
    为便于数组处理,整体向右偏移n-1,则 row - col + n-1 = 0 ~ 2n-2
  • 对角线 / : row + col = 0 ~ 2n-2

若逐行填入queen,那么row是否有效可选不必记录;同理,若逐列填写,那么col不必记录。

class Solution {
    
    
public:
    int N;
    vector<bool> col, ddiag, udiag;
    vector<string> temp;
    vector<vector<string>> ans;

    vector<vector<string>> solveNQueens(int n) {
    
    
        N = n;
        col.resize(n, 1);
        ddiag.resize(2*n-1, 1);
        udiag.resize(2*n-1, 1);
        for(int c=0; c<n; c++) DFS(0, c);
        return ans;
    }

    //put queen at [r][c]
    void DFS(int r, int c){
    
    
        //put queen
        string s(N, '.');
        s[c] = 'Q';
        temp.emplace_back(s);
        //recursion exit
        if(r==N-1){
    
    
            ans.emplace_back(temp);
            temp.pop_back();
            return;
        }
        //reduce options
        col[c] = false;
        ddiag[r-c+N-1] = false;
        udiag[r+c] = false;
        //check [r+1][...]
        for(int i=0; i<N; i++){
    
    
            if(col[i] && ddiag[r-i+N] && udiag[r+1+i]){
    
    
                DFS(r+1, i);
            }
        }
        //roll back
        col[c] = true;
        ddiag[r-c+N-1] = true;
        udiag[r+c] = true;
        temp.pop_back();
        return;
    }
};

猜你喜欢

转载自blog.csdn.net/sinat_37517996/article/details/105689479