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;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值