nクイーンパズル

Nクイーンパズル

数学の解

解決策はユニークではありません、この方法はそれらのうちの1つだけを提供します。
ここに画像の説明を挿入

DFS

4つの配列を使用して、位置のオプションの状態を記録します。入力された各ポイントについて、障害の原因となる行、列、および2つの対角線は一意である必要があるため、DFSでオプションの状態を復元すると便利です。複数のポイントが原因で同じポイントが無効になる可能性があるため、レコードポイント[row] [col]よりも便利です。

  • 対角線\:row - col = -(n-1) ~ n-1
    配列処理を容易にするために、全体がn-1だけ右にオフセットされ、次にrow - col + n-1 = 0 ~ 2n-2
  • 対角/: row + col = 0 ~ 2n-2

クイーンを行ごとに入力する場合は、行が有効かどうかを記録する必要はありません。同様に、列ごとに入力する場合は、列を記録する必要はありません。

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