n皇后问题 额 曾经还年轻的时候写过 回溯嘛 很常用的思路 但是在写的时候出问题了! 我不知道怎么判断是否在同一对角线上了 。。。 首先明确 回溯法 使用集合 unordered_set <int> 保证不在同一列和同一斜线(stl还是用的少。。。) columns 保证不在同一列上 diagonal 保证不在同一正斜线上 backdiagonal 保证不在同一反斜线上 (md 我一开始想用queue 实现回溯的 结果越写越乱 然后看的题解 我好菜啊。。。)
class Solution { public: vector<vector<string>> solveNQueens(int n) { // ans 返回 vector<vector<string>> ans; // queens 记录本次的答案 vector<int> queens(n,-1); unordered_set<int> columns; unordered_set<int> diagonal; unordered_set<int> backdiagonal; solve(ans,queens,n,0,columns,diagonal,backdiagonal); return ans; } void solve(vector<vector<string>>& ans,vector<int>& queens,int n,int row,unordered_set<int>& columns,unordered_set<int>& diagonal, unordered_set<int> &backdiagonal){ if(row==n){ // 结束 答案正确 vector<string> s=getans(queens, n); ans.push_back(s); }else{ // 第row行的n种情况(列) for(int i=0;i<n;++i){ // 行 斜线 if(columns.find(i)!=columns.end()){ continue; } int diag=row-i; if(diagonal.find(diag)!=diagonal.end()){ continue; } int backdiag=row+i; if(backdiagonal.find(backdiag)!=backdiagonal.end()){ continue; } // queens 集合 queens[row]=i; columns.insert(i); diagonal.insert(diag); backdiagonal.insert(backdiag); solve(ans,queens,n,row+1,columns,diagonal,backdiagonal); // 去除 保证下次递归正确 queens[row]=-1; columns.erase(i); diagonal.erase(diag); backdiagonal.erase(backdiag); } } } // queens记录位置 转化为vector<string> vector<string> getans(vector<int> &queens,int n){ vector<string> ans; for(auto a:queens){ string s=string(n, '.'); s[a]='Q'; ans.push_back(s); } return ans; } };还有个更好的查询方法 (大佬nb 我是想不出来的菜鸟 ) 使用二进制数 记录个坐标 写的还很清楚 题解(我感觉我会忘记的。。。) 不过设置为 int 最大长度就是64了吧
将数值(int) 写为 2 进制的 每一位代表该行的一个位置(0代变可以 1代表不可) columns 保证不在同一列上 diagonal 保证不在同一正斜线上 backdiagonal 保证不在同一反斜线上 对于 diagonal backdiagonal ,下一行的不能放皇后的位置是上一行的 diagonal 左移 和 backdiagonal 的右移 x & (−x) 可以获得 x 的二进制表示中的最低位的 1 的位置 x & (x−1) 可以将 x 的二进制表示中的最低位的 1 置成 0 class Solution { public: vector<vector<string>> solveNQueens(int n) { vector<vector<string>> ans; vector<int> queens(n,-1); solve(ans,queens,n,0,0,0,0); return ans; } void solve(vector<vector<string>>& ans,vector<int>& queens,int n,int row,int columns,int diagonal, int backdiagonal){ if(row==n){ vector<string> s=getans(queens, n); ans.push_back(s); }else{ int pos=((1<<n)-1)&(~(columns|diagonal|backdiagonal)); while(pos!=0){ int postion=pos&(-pos); pos=pos&(pos-1); int column=__builtin_ctz(postion); queens[row]=column; solve(ans,queens,n,row+1,columns|postion,(diagonal|postion)>>1,(backdiagonal|postion)<<1); queens[row] = -1; } } } vector<string> getans(vector<int> &queens,int n){ vector<string> ans; for(auto a:queens){ string s=string(n, '.'); s[a]='Q'; ans.push_back(s); } return ans; } };