八皇后
思路:递归、回溯
数据结构:用二维数组存储棋盘放置情况以及棋盘标记,递归修改之。
1. 棋盘放置情况location:棋盘中皇后位置,皇后位置为‘Q’,初始为‘.’
2. 棋盘标记mark:当前棋盘还可以放置皇后的位置,无法放置的位置为1,可以放置的位置为0
3. 结果数组results:存储所有棋盘情况,当n个皇后摆放完成时,将当前location存在results中
/*八皇后-递归、回溯*/
#include<bits\stdc++.h>
using namespace std;
vector<vector<string> >results;//棋盘结果
vector<vector<int> >mark;//初始为0,皇后以及皇后可达位置为1
vector<string> location;//初始化为“.”,皇后位置为“Q”
//int k;//当前完成摆放的皇后数量 ,初始值为0
int n;//n个皇后,棋盘n*n
/*初始化数组*/
void initVe(){
results.clear();
mark.clear();
location.clear();
for(int i=0;i<n;i++){
mark.push_back((vector<int>()));
for(int j=0;j<n;j++){
mark[i].push_back(0);
}
location.push_back("");
location[i].append(n,'.');
}
}
//将棋盘上(x,y)坐标位置放置皇后,并且将皇后能到达的地方mark数组置为1
void putDownTheQueen(int x,int y,vector<vector<int> > &mark){
static const int dx[] = {-1,1,0,0,-1,-1,1,1};//上下左右左上右上左下右下
static const int dy[] = {0,0,-1,1,-1,1,-1,1};
mark[x][y] = 1;//(x,y)位置放置皇后
/*把该皇后能到达的位置设置为1*/
for(int i=1;i<mark.size();i++){
for(int j=0;j<8;j++){
int new_x = x + i * dx[j];
int new_y = y + i * dy[j];
/*及时判断是否越界*/
if(new_x >= 0 && new_x < n && new_y >= 0 && new_y < n){
mark[new_x][new_y] = 1;
}
}
}
}
//产生棋盘
void generate(int k,vector<string> &location,vector<vector<string> > &results,vector<vector<int> > &mark){
//先写终止条件
if(k == n){
//0~n-1个皇后(共n个)已经放好,将此种皇后放置情况保存起来
results.push_back(location);
return ;
}
for(int i = 0; i < n ; i ++){//棋盘上第k行第i列依次遍历
if(mark[k][i] == 0){
//此位置可以放皇后
vector<vector<int> >temp = mark;//存储还没放皇后时候的mark数组,用于回溯
location[k][i] = 'Q';
putDownTheQueen(k,i,mark);
generate(k+1,location,results,mark);
mark = temp;//回溯
location[k][i] = '.';
}
}
}
int main(){
cin>>n;
initVe();
generate(0,location,results,mark);//从第0行开始进行递归
cout<<"可能情况:"<<results.size()<<endl;
for(int i = 0 ; i < results.size() ; i ++){
cout<<"第"<<i+1<<"种:"<<endl;
vector<string> tempLocation = results[i];
for(int j = 0 ; j < tempLocation.size() ; j ++){
cout<<tempLocation[j]<<" ";
cout<<endl;
}
}
return 0;
}