n queens ii(n皇后问题-只计数不保存)

n皇后问题2(保存并返回所有的解决方案)

题目描述

Follow up for N-Queens problem.
Now, instead outputting board configurations, return the total number of distinct solutions.

题目大意

著名n皇后问题。
n个皇后摆放在N x N的棋盘格中,使得横、竖和两个对角线方向均不会同时出现两个皇后。
只返回解决方案总数

思路

n皇后问题当n大于等于4才有讨论意义,而且不只有一个解决方案;
用递归的方法找到每一种解决方案;
在当前解决方案中,遍历每一行的每一列查找可以放置皇后的位置;
在当前行中,遍历每一列的每一个位置,假设当前位置可以放,然后进行合法性判断,合法则放置;
然后再递归判断下一行;
递归结束后,将当前行当前列的位置回溯,置为未放状态,再接着判断当前行下一列,目的是为了找到所有的解决方案。

代码

#include<iostream>
#include<vector>
using namespace std;
/*
    函数声明
*/
// n皇后问题解决函数
int totalNQueens(int n);
// 递归实现深度优先搜索寻找解决方案
void dfs(vector<string > &arr, int n, int row, int &sum);
// 判断当前arr[row][col]是否可以放一个皇后
bool is_valid(vector<string > &arr, int n, int row, int col);
/*
    n:n皇后问题
*/
int totalNQueens(int n)
{
    vector<string > arr(n, string(n, '.'));
    int sum = 0;
    dfs(arr, n, 0, sum);
    return sum;
}
/*
    arr:用这个数组保存得到的n皇后问题的当前解决方案
    n:n皇后问题
    row:递归寻找当前行的皇后放在哪一列
    sum:总的解决方案数
*/
void dfs(vector<string > &arr, int n, int row, int &sum)
{
    if(row == n)
    {
        sum++; // 解决方案数加一
        /* 输出解决方案
        for(int i=0; i<n; i++)
        {
            for(int j=0; j<n; j++)
            {
                cout<<arr[i][j]<<' ';
            }
            cout<<endl;
        }
        */
        return;
    }
    for(int i=0; i<n; i++)
    {
        // 判断是否可以在arr[row][i]放一个皇后
        if(is_valid(arr, n, row, i))
        {
            arr[row][i] = 'Q';
            dfs(arr, n, row+1, sum); // 递归判断下一列
            arr[row][i] = '.'; // 回溯判断下一列
        }
    }
}
/*
    arr:用这个数组保存得到的n皇后问题的当前解决方案
    n:n皇后问题
    row、col:当前判断的是第row行、第col列
*/
bool is_valid(vector<string > &arr, int n, int row, int col)
{
    // 检查列
    for(int i=0; i<row; i++)
    {
        if(arr[i][col] == 'Q')
        {
            return false;
        }
    }

    // 检查对角线
    for(int i=row-1,j=col-1; i>=0&&j>=0; i--,j--)
    {
        if(arr[i][j] == 'Q')
        {
            return false;
        }
    }

    // 检查副对角线
    for(int i=row-1,j=col+1; i>=0&&j<n; i--,j++)
    {
        if(arr[i][j] == 'Q')
        {
            return false;
        }
    }

    return true;
}

int main()
{
    cout << "请输入皇后的个数:" << endl;
    int n;
    cin >> n;
    cout << n << "皇后问题共有 " << totalNQueens(n) << " 种解决方案。" << endl;
    return 0;
}

运行结果

以上。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值