回溯法--N皇后问题

一般是八皇后,首先是算法思想如下:

void generate(int n){
	int col;
	for(col=0;col<=7;col++){
		if(不冲突){
			放置,并且宣布占领
			if(n<7){
				generate(n+1);
			}else{
				printf();//打印 
			}
			回溯,取消占领. 
		}
	}
}

主函数如下:首先从0开始,也就是第一行开始逐级向下

int main(){
	generate(0);
	cout<<"摆放方式有:"<<counts<<"种!"<<endl;
	return 0;
}

递归函数如下:

void generate(int n){
	int col;
	for(col=0;col<8;col++){//棋盘一共八行八列,此处主要是每一层用于判断每一列是否符合条件 
		if(flag[col]&&d1[n-col+7]&&d2[n+col]){//括号内是算法的精髓,理解了此处,N皇后问题就不难,主要是根据八皇后棋盘的性质,
		                                      //如两个坐标,如果行数-列数对应的值相同,那么就必然在同一对角线,此时跳出if从而判断下一位置 
			Queens[n]=col;//符合上述条件之后,就把皇后放置在col列,并且把相对于的列,上对角线,下对角线的标记改为false,方便之后的判断 
			flag[col]=false;
			d1[n-col+7]=false;
			d2[n+col]=false;
			if(n<7){
				generate(n+1);
			}else{
				print();
			}
			flag[col]=true;//回溯考虑上一层的情况,并且把这一层改过来的false改为true 
			d1[n-col+7]=true;
			d2[n+col]=true;
		}
	}
}

输出函数如下:

void print(){
	int col,i,j;
	counts++;
	cout<<"No."<<counts<<endl;
	int table[8][8]={};//定义一个8*8的棋盘数组,起始每个元素都是0 
	for(col=0;col<8;col++){
		table[col][Queens[col]]=1;//Queens[col]保存的是皇后所在的列数 
	}
	for(i=0;i<8;i++){
		for(j=0;j<8;j++){
			cout<<table[i][j]<<" ";
		}
		cout<<endl;
	}
}

头部声明以及全局变量如下:

#include <iostream>
#include <algorithm>
using namespace std;
int Queens[8]={};//表示第n个皇后占位置的列号 
int counts=0;//counts记录能摆放的棋盘方式个数 
bool flag[8]={1,1,1,1,1,1,1,1};//标志数组,表示第col列是否可占,1表示可占 
bool d1[15]={1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};//表示上对角线是否可占 为什么是15呢?
//因为在d1[n-col+7]中为了避免出现负数,所以要+7,而原来可能是7的现在变成了14 
bool d2[15]={1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};//表示下对角线是否可占  

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值