首页 > 学院 > 开发设计 > 正文

51. N-Queens/52. N-Queens II

2019-11-08 00:44:15
字体:
来源:转载
供稿:网友

八皇后问题参考这张图片:

51

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:[ [".Q..", // Solution 1 "...Q", "Q...", "..Q."], ["..Q.", // Solution 2 "Q...", "...Q", ".Q.."]]Subscribe to see which companies asked this question.

解法:

class Solution {public: vector<vector<string>> solveNQueens(int n) { vector<vector<string>> res; if(n < 0) return res; vector<string> nqueue(n, string(n, '.')); solve_nqueue(res, nqueue, 0, n); return res; }private: void solve_nqueue(vector<vector<string>>& res, vector<string>& nqueue, int row, int n) { if(row == n){ res.push_back(nqueue); return ; } for(int col=0; col<n; ++col){ if(is_valid(nqueue, row, col, n)){ nqueue[row][col] = 'Q'; solve_nqueue(res, nqueue, row+1, n); nqueue[row][col] = '.'; } } } bool is_valid(vector<string>& nqueue, int row, int col, int n){ for(int i=0; i<n; ++i){ //检查列 if(nqueue[i][col] == 'Q' && i != row) return false; } for(int i=row-1, j=col-1; i>=0 && j>=0; --i, --j){ //检查135° if(nqueue[i][j] == 'Q') return false; } for(int i=row-1, j=col+1; i>=0 && j<n; --i, ++j){ //检查45°,所有的检查都只需要检查已填充的上半部分 if(nqueue[i][j] == 'Q') return false; } return true; }};

51是要返回所有的结果,并且使用到了string。这里一个不常用的技巧就是vector< string>作为二维数组,也是很好用呢。

52

Follow up for N-Queens problem.Now, instead outputting board configurations, return the total number of distinct solutions.class Solution {public: int totalNQueens(int n) { vector<int> nqueue(n, -1); //初始化为-1,不能为0,因为后面要用0 int counter = 0; solve_nqueue(nqueue, 0, n, counter); return counter; }private: void solve_nqueue(vector<int>& nqueue, int row, int n, int& counter) { if(row >= n) { ++counter; return; } for(int col=0; col<n; ++col){ nqueue[row] = col; if(is_valid(nqueue, row, n)) solve_nqueue(nqueue, row+1, n, counter); } } bool is_valid(vector<int>& nqueue, int row, int n) { for(int i=0; i<row; ++i){ if(abs(i-row) == abs(nqueue[i]-nqueue[row]) || abs(nqueue[i] == nqueue[row])) return false; } return true; }};

52题只需要返回解法的个数,我使用了一个巧妙的解法,就是使用一维数组index表示row,nqueue[row]表示在该row行nqueue列放置皇后。

然后判断是否有效,使用了一个trick,详见: N皇后问题 –递归及回溯解决方案。


上一篇:抽象工厂

下一篇:浅谈JS继承(三)

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表