版权声明:本文为博主原创文章,转载请注明出处。个人博客地址:https://yangyuanlin.club/ 欢迎来踩~~~~ https://blog.csdn.net/w7239/article/details/85346233
题目描述
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;
}
运行结果
以上。