51. N皇后

问题

按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。

n 皇后问题 研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击。

给你一个整数 n ,返回所有不同的 n 皇后问题 的解决方案。

每一种解法包含一个不同的 n 皇后问题 的棋子放置方案,该方案中 'Q' 和 '.' 分别代表了皇后和空位。

分析

正常dfs回溯即可,难度不如131分割回文串。子问题是当前行的棋子放在哪一列,需记录哪一列不能放,包括列和两个对角线原因。对角线需要转化,左上到右下用x-y为定值;右上到左下用x+y为定值,可用map或者set存储这些定值,需要判断是否可放时find或count即可。

代码

class Solution {
public:
    vector<vector<string> > res;
    int n;
    int st_col[10];
    unordered_map<int, int> lr; // top-left to bottom-right
    unordered_map<int, int> rl;
    void dfs(vector<string> v_s, int x) { // x row
        if (x == n) {
            res.push_back(v_s);
            return ;
        }
        for (int i = 0; i < n; i++) {
            if (st_col[i]) {continue;}
            if (lr.find(x-i) != lr.end()) {continue;}
            if (rl.find(x+i) != rl.end()) {continue;}
            v_s[x][i] = 'Q';
            st_col[i] = 1;
            lr.insert(make_pair(x-i, 1));
            rl.insert(make_pair(x+i, 1));
            dfs(v_s, x+1);
            v_s[x][i] = '.';
            st_col[i] = 0;
            lr.erase(x-i);
            rl.erase(x+i);
        }
    }
    vector<vector<string>> solveNQueens(int n) {
        this->n = n;
        vector<string> v_s(n, string(n, '.'));
        dfs(v_s, 0);
        return res;
    }
};

new

时隔很久,我还是能写出n皇后,开心。但是要注意diffst中x-i可能为负,所以整体加偏移+n。

当然,用哈希的话,就可以直接存负了。

class Solution {
private:
    int cst[12];
    vector<vector<string>> res;
    int n;
    int sumst[22], diffst[22];
    void dfs(int x, vector<string> t) {
        if (x >= n) {
            res.push_back(t); return ;
        }
        string s(n, '.');
        for (int i = 0; i < n; i++) { // col
            if (cst[i]) {continue;}
            if (sumst[x+i]) {continue;}
            if (diffst[x-i+n]) {continue;}
            s[i] = 'Q';
            cst[i] = 1; sumst[x+i] = 1; diffst[x-i+n] = 1;
            t.push_back(s);
            dfs(x+1, t);
            t.pop_back();
            s[i] = '.';
            cst[i] = 0; sumst[x+i] = 0; diffst[x-i+n] = 0;
        }
    }
public:
    vector<vector<string>> solveNQueens(int n) {
        memset(cst, 0, sizeof cst);
        memset(sumst, 0, sizeof sumst);
        memset(diffst, 0, sizeof diffst);
        this->n = n;
        dfs(0, {});
        return res;
    }
};
posted @ 2025-06-06 15:47  saulstavo  阅读(40)  评论(0)    收藏  举报