标签:
这个题的意思是让我们求“n 后问题”的解法的数目,其实和上一个题基本是相似的,只需要做少量的改动就行,主要的思路如下:
1.使用 vector<string> 保存每一层的Queen的位置,然后往下一层递归,测试下一层Queen的位置,若符合要求就继续上下测试,若不符合则更换位置继续测试。
2.测试函数的编写需要注意,记得斜线上的点的测试,假设我们先将Queen置于中心上,那么该点的左右,上下,以及左上方和右下方,左下方和右上方等等都需要考虑到,不要漏掉任何一点,而且需要考虑边界问题。
3.在程序中我们应该提前检测,意思就是不要递归到最后一层才检查当前方案是否合格,我们在每一层的每个位置都需要检查是否合格,这样可以提前做出决策,这样可以大大减少递归的次数,提高程序的效率。
下面我就给出代码:
class Solution { public: int totalNQueens(int n) { int ret = 0; vector<string> oneSolve; oneSolve.clear(); for (int i = 0; i < n; ++i) { string tmp(n, '.'); oneSolve.push_back(tmp); } _solves(ret,oneSolve, n, 0); return ret; } void _solves(int &ret,vector<string> oneSolve, int n, int index) { if (index == n) { ++ret; return; } for (int i = 0; i < n; ++i) { oneSolve[index][i] = 'Q'; if (!_testQueen(oneSolve, index + 1, n)) {//检查当前行,提前做出决策 oneSolve[index][i] = '.'; continue; } _solves(ret, oneSolve, n, index + 1); oneSolve[index][i] = '.'; } } bool _testQueen(vector<string>& tmp, int m, int n) { // m行,n列(m可能小于n) int i = m - 1; int j = 0; for (; j < n; ++j) { if (tmp[i][j] == 'Q') { break; } } // tmp[i][j] == 'Q' // 检查行 for (int k = j + 1; k < n; ++k) { if (tmp[i][k] == 'Q') { return false; } } //检查列 for (int k = 0; k < i; ++k) { if (tmp[k][j] == 'Q') { return false; } } for (int k = i + 1; k < m; ++k) { if (tmp[k][j] == 'Q') { return false; } } //检查斜线上的 //左上 int beginx = i; int beginy = j; while (beginx > 0 && beginy > 0) {// if (tmp[--beginx][--beginy] == 'Q') { return false; } } //右下 beginx = i; beginy = j; while (beginx < m - 1 && beginy < n - 1) { if (tmp[++beginx][++beginy] == 'Q') { return false; } } //左下 beginx = i; beginy = j; while (beginx<m - 1 && beginy > 0) { if (tmp[++beginx][--beginy] == 'Q') { return false; } } //左上 beginx = i; beginy = j; while (beginx > 0 && beginy < n - 1) { if (tmp[--beginx][++beginy] == 'Q') { return false; } } return true; } };程序的结果如下:
标签:
原文地址:http://blog.csdn.net/zr1076311296/article/details/51495738