八皇后问题是指在一个8乘以8的棋盘上放置八个皇后,它们不能在同一行同一列以及同一对角线上,有多少种放法。
解决思路:用二维数组表示棋盘,初始为全0,放置皇后则将值置1。当全部放置好了,就将计数器加1。最后输出计数器。无论成功还是失败,都进行回溯。
#include <vector>
#include <iostream>
using namespace std;
//负责放置皇后的函数
void place(vector<vector<int>> & chess, int & count, int & number, int size, int start);
int main()
{
int n = 8; //棋盘大小
vector<vector<int>> chess;
chess.reserve(n);
vector<int> temp(n, 0);
//初始化棋盘为全0
for(int i = 0; i < n; ++i)
{
chess.push_back(temp);
}
int count = 0; //计数器
int number = n; //剩余需要放置的皇后数量,为零时表示成功,计数器加1
//开始放置
place(chess, count, number, n, 0);
cout << count << endl;
}
//判断该位置是否可以放置
bool isSafe(const vector<vector<int>> & chess, int i, int j);
//start代表下一个放置点开始的行数,为上一个放置点的下一行。避免出现计入重复的情况
void place(vector<vector<int>> & chess, int & count, int & number, int n, int start)
{
//遍历所有点
for(int i = start; i < n; ++i)
{
for(int j = 0; j < n; ++j)
{
//该点可以放置
if(chess[i][j] == 0 && isSafe(chess, i, j))
{
chess[i][j] = 1;
--number;
//全部放完,计数器加1,回溯状态。寻找下一种可能,因为最后一个肯定只有一种可能,所以直接return
if(number == 0)
{
++count;
chess[i][j] = 0;
++number;
return;
}
//放置下一个皇后
place(chess, count, number, n, i + 1);
//放置完毕,无论成功与否,回溯状态,寻找下一种可能
chess[i][j] = 0;
++number;
}
}
}
}
bool isSafe(const vector<vector<int>> & chess, int i, int j)
{
for(int k = 0; k < chess.size(); ++k)
{
if(chess[k][j])
return false;
if(chess[i][k])
return false;
}
int tempi = i + 1, tempj = j + 1;
while((tempi < chess.size() && tempi >= 0) && ((tempj < chess.size() && tempj >= 0)))
{
if(chess[tempi][tempj])
return false;
++tempi;
++tempj;
}
tempi = i - 1; tempj = j - 1;
while((tempi < chess.size() && tempi >= 0) && ((tempj < chess.size() && tempj >= 0)))
{
if(chess[tempi][tempj])
return false;
--tempi;
--tempj;
}
tempi = i - 1; tempj = j + 1;
while((tempi < chess.size() && tempi >= 0) && ((tempj < chess.size() && tempj >= 0)))
{
if(chess[tempi][tempj])
return false;
--tempi;
++tempj;
}
tempi = i + 1; tempj = j - 1;
while((tempi < chess.size() && tempi >= 0) && ((tempj < chess.size() && tempj >= 0)))
{
if(chess[tempi][tempj])
return false;
++tempi;
--tempj;
}
return true;
}
最后输出92