八皇后-递归+回溯-c++实现

八皇后

思路:递归、回溯

数据结构:用二维数组存储棋盘放置情况以及棋盘标记,递归修改之。

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;
} 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值