leetcode#51 N皇后

这篇博客探讨了如何利用深度优先搜索(DFS)和状态压缩技术来解决经典的N皇后问题。通过32位整数表示棋盘状态,避免皇后间的攻击。博主给出了详细的代码实现,包括初始化棋盘、检查皇后位置合法性和递归搜索等功能,展示了如何找到所有不同的解决方案。示例中展示了当n为4时,问题的两个不同解法。
摘要由CSDN通过智能技术生成

leetcode#51 N皇后

题目:

n 皇后问题 研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击。
给你一个整数 n ,返回所有不同的 n 皇后问题 的解决方案。
每一种解法包含一个不同的 n 皇后问题 的棋子放置方案,该方案中 ‘Q’ 和 ‘.’ 分别代表了皇后和空位。
皇后彼此不能相互攻击,也就是说:任何两个皇后都不能处于同一条横行、纵行或斜线上。

示例:

N皇后

输入:n = 4
输出:[[".Q..","...Q","Q...","..Q."],["..Q.","Q...","...Q",".Q.."]]
解释:如上图所示,4 皇后问题存在两个不同的解法。

思路:dfs+状态压缩

以前写过不带状态压缩的这次写个状态压缩的。

row:32位足够表示32行,实际上可以省略,我们可以按行搜索。
colume:32位足够表示32列。
dia1:正对角线 i+j;
dia2:反对角线 i-j+len+1;

代码:

class Solution
{
public:
    int len;
    vector<vector<string>> ans;
    vector<string> now;
    int row, colume, dia1, dia2,sum;
    void init()
    {
        for (int i = 0; i < len; ++i)
        {
            string tmp;
            now.push_back(tmp);
            for (int j = 0; j < len; ++j)
                now[i].push_back('.');
        }
        return;
    }
    // void print()
    // {
    //     for (int i = 0; i < now.size(); ++i)
    //     {
    //         for (int j = 0; j < now[i].length(); ++j)
    //             cout << now[i][j] << ' ';
    //         cout << endl;
    //     }
    //     cout << endl;
    // }
    void dfs(int step)
    {
        if (step == len)
        {
            ans.push_back(now);
            sum++;
            return;
        }
        for (int i = 0; i < len; ++i)
        {
            int r = 1 << step;
            int col = 1 << i;
            int d1 = 1 << i + step;
            int d2 = 1 << step - i + len - 1;
            if (now[step][i] == '.' && !(row & r) && !(col & colume) && !(d1 & dia1) && !(d2 & dia2))
            {
                row ^= r;
                colume ^= col;
                dia1 ^= d1;
                dia2 ^= d2;
                now[step][i] = 'Q';
                dfs(step + 1);
                now[step][i] = '.';
                dia2 ^= d2;
                dia1 ^= d1;
                colume ^= col;
                row ^= r;
            }
        }
        return;
    }
    int totalNQueens(int n)
    {
        row = 0, colume = 0, dia1 = 0, dia2 = 0, sum=0,len = n;
        init();
        dfs(0);
        return sum;
    }
};
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值