51. N-Queens Hard

来源:互联网 发布:java 泛型 多继承 编辑:程序博客网 时间:2024/06/05 01:01

经典的八皇后问题,主要考查回溯法。参考前面一篇转载别人的结束回溯法的文章,里面的模版很规范很实用。

这里提供两种解法。主要思想都是从矩阵的第0行开始,每一行从左开始尝试摆一个棋子,然后看这个位置是否合适,如果合适,则将这个矩阵递归下去;如果不合适,则看下一个位置,直到这一行的位置都被尝试过。函数持续递归调用到第n行,就把结果添加到答案中。第一种代码如下:

class Solution {
public:
    vector<vector<string> > solveNQueens(int n) {
        vector<vector<string> > results;
        vector<string> matrix(n, string(n, '.'));
        backtracking(0, n, matrix, results);
        return results;
    }
private:
    void backtracking(int row, int n, vector<string>& matrix, vector<vector<string> >& results)
    {
    if(row == n){
    results.push_back(matrix);
    return ;
    }
    for (int i = 0; i < n; ++i)
    {
       if(isValid(row, i ,matrix)){
           matrix[row][i] = 'Q';
           backtracking(row + 1, n, matrix, results);
           matrix[row][i] = '.'; 
       }
    }
   
    }
    bool isValid(int x, int y, vector<string> matrix)
    {
    for (int i = 0; i != x; ++i)
            if (matrix[i][y] == 'Q')
                return false;
    //check if the 45° diagonal had a queen before.
        for (int i = x - 1, j = y - 1; i >= 0 && j >= 0; --i, --j)
            if (matrix[i][j] == 'Q')
                return false;
        //check if the 135° diagonal had a queen before.
        for (int i = x - 1, j = y + 1; i >= 0 && j < matrix.size(); --i, ++j)
            if (matrix[i][j] == 'Q')
                return false;
    return true;
    }
};


第二种做法的思路是一样的,区别在于isValid函数,即判断当前摆法是否合适的方法不同。第二种用到三个数组(答案用了vector<int>,其实用bool数组也一样),分别表示矩阵的n列、45度对角线和135度对角线上是否出现过棋子,如果出现,既为0,否则为1。第一个数组长度为n,记录n列;第二个数组长度为2*n-1,记录45度对角线(同一条对角线上的点的坐标 x+y的值都相等);第三个数组长度为2*n-1, 记录135度(同一条对角线上点的坐标 y - x + n的值都相等)。

class Solution {
public:
    vector<vector<string> > solveNQueens(int n) {
        vector<vector<string> > res;
        vector<string> nQueens(n, string(n, '.'));
        vector<int> flag_col(n, 1), flag_45(2 * n - 1, 1), flag_135(2 * n - 1, 1);
        solveNQueens(res, nQueens, flag_col, flag_45, flag_135, 0, n);
        return res;
    }
private:
    void solveNQueens(vector<vector<string> > &res, vector<string> &nQueens, vector<int> &flag_col, vector<int> &flag_45, vector<int> &flag_135, int row, int &n) {
        if (row == n) {
            res.push_back(nQueens);
            return;
        }
        for (int col = 0; col != n; ++col)
            if (flag_col[col] && flag_45[row + col] && flag_135[n - 1 + col - row]) {
                flag_col[col] = flag_45[row + col] = flag_135[n - 1 + col - row] = 0;
                nQueens[row][col] = 'Q';
                solveNQueens(res, nQueens, flag_col, flag_45, flag_135, row + 1, n);
                nQueens[row][col] = '.';
                flag_col[col] = flag_45[row + col] = flag_135[n - 1 + col - row] = 1;
            }
    }
};


0 0
原创粉丝点击