标签:
The n-queens puzzle is the problem of placing n queens on an n×n chessboard such that no two queens attack each other.
Given an integer n, return all distinct solutions to the n-queens puzzle.
Each solution contains a distinct board configuration of the n-queens‘ placement, where ‘Q‘
and ‘.‘
both indicate a queen and an empty space respectively.
For example,
There exist two distinct solutions to the 4-queens puzzle:
N后问题是将N个皇后分布在一个N*N的棋盘上,使得任意两个皇后都不能互相攻击。输出是一个类似矩阵的字符串数组,用‘Q‘来表示皇后,‘.‘表示空白。
不能相互攻击暗示了它们不能位于同一行或是同一列,且不能位于同一个正或反对角线上。
这道题在本质上和数独是一个问题,可回溯亦可递归。在这里可以按照行来进行迭代,每一行有N个分支,分别考虑这些分支的合法性,然后往下一行迭代即可。如此不在同一行是自然可以保证的,列和对角线的占用情况可以使用bool数组来表示,对于列来说会有N个slot,而对于正反两种对角线来说有N*2-1个slot。
算法的复杂度是O(NN),给出代码如下:
vector<bool> col; vector<bool> x; vector<bool> y; bool Check(int i, int j, int n);
void Set(int i, int j, bool b, int n);
vector<string> convert(vector<int>& R);
vector<vector<string>> solveNQueens(int n) { col.assign(n, false); x.assign(2*n, false); y.assign(2*n, false); vector<vector<string>> ret; int i = 0; vector<int> R(n, -1); while (i>=0) { if (i==n) { ret.push_back(convert(R)); --i; } int j = R[i]; if (j != -1) { Set(i, j, false, n); R[i] = -1; } for (++j; j<n; ++j) { if (Check(i, j, n)) { Set(i, j, true, n); R[i] = j; break; } } if (R[i] != -1) ++i; else --i; } return ret; }
bool Check(int i, int j, int n) { if (col[j]) return false; if (x[i-j+n]) return false; if (y[i+j]) return false; return true; }
void Set(int i, int j, bool b, int n) { col[j] = b; x[i-j+n] = b; y[i+j] = b; }
vector<string> convert(vector<int>& R) { int n = R.size(); vector<string> ret; for (auto i : R) { string str(n, ‘.‘); str[i] = ‘Q‘; ret.push_back(str); } return ret; }
标签:
原文地址:http://www.cnblogs.com/zhiguoxu/p/5477232.html