目录
将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击。
题干
在国际象棋中,即将n个棋子放到n*n的棋盘上,使得每个棋子不能同行,不能同列,不能同斜线。
回溯算法
回溯算法实际上是穷举所有的可能性,在这个规则中,我们可以发现由于每一行只能有一个棋子,我们可以逐层确定棋子的位置,每一个棋子是否能落下再由前面的棋子落点确定。
回溯部分代码如下:
void backtracking(int row,int n,vector<string>& chess)
{
//先确定终止条件
if(n==row)
{
result.push_back(chess);
}
for(int i=0;i<chess[0].size();i++)
{
//判断落点是否合适
if(IsVaild(row,i,chess))
{
chess[n][i]='Q';
//进入下层
backtracking(row+1,n,chess);
//回溯
chess[n][i]='.';
}
else
{
continue;
}
}
}
row是目前所在行,n是所给的棋盘n*n大小,在每一层递归中,我们确定一层的'Q',在向下一层,如果某一层没有一个棋子可以落下,则回溯,并将上一层的'Q'向后移一位。
判断落点
只需要在竖向,两条斜向上判断,且只需要判断落点上方的情况。
bool IsVaild(int x,int y,vector<string> chess)
{
//竖向
for(int i=x-1;i>=0;i--)
{
if(chess[i][y]=='Q')
{
return false;
}
}
//斜向上两条
for(int i=x-1.j=y-1;i>=0,j>=0;i--,j--)
{
if(chess[i][j]=='Q';)
{
return false;
}
}
for(int i=x-1.j=y+1;i>=0,j<chess[0].size();i--,j++)
{
if(chess[i][j]=='Q';)
{
return false;
}
}
}
整体代码
#include <iostream>
#include <vector>
#include <string>
using namespace std;
class solution
{
private:
vector<vector<string>> result;
void backtracking(int row,int n,vector<string> chessboard)
{
if(row==n)
{
result.push_back(chessboard);
return;
}
for(int i=0;i<n;i++)
{
if(IsVaild(row, i, n, chessboard))
{
chessboard[row][i]='Q';
backtracking(row+1, n, chessboard);
chessboard[row][i]='.';
}
else
{
continue;
}
}
}
bool IsVaild(int x/*row*/,int y,int n,vector<string>& chessboard)
{
for(int i=x;i>=0;i--)
{
if(chessboard[i][y]=='Q')
{
return false;
}
}
for(int ix=x-1,iy=y-1;ix>=0&&iy>=0;ix--,iy--)
{
if(chessboard[ix][iy]=='Q')
{
return false;
}
}
for(int ix=x-1,iy=y+1;ix>=0&&iy<n;ix--,iy++)
{
if(chessboard[ix][iy]=='Q')
{
return false;
}
}
return true;
}
public:
vector<vector<string>> results(int n)
{
result.clear();
vector<string> chessboard(n,string(n,'.'));
backtracking(0, n, chessboard);
return result;
}
};
int main() {
std::cout << "Hello World!\n";
solution so;
int m=5;
for(auto i:so.results(m))
{
for(auto j:i)
{
for(auto k:j)
{
cout<<k<<' ';
}
cout<<endl;
}
cout<<"--------------------- --"<<endl;
}
cout<<so.results(m).size()<<endl;
}