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