八皇后问题 二维、一维、回溯

在 8×8 的国际象棋棋盘上放置八个皇后,使得任何一个皇后都无法直接吃掉其他的皇后?

为了达到此目的,任两个皇后都不能处于同一条横行、纵行或斜线上。

下面代码是输出所有可能的皇后排列方法 共92种

//八皇后问题 
#include<iostream>
using namespace std;
int c[8],q[8][8];//q[8][8]是用来记录皇后的位置的 c[8]是用来记录着一列有没有皇后 
void dfs(int count);
bool judge(int row,int col);//用来判断斜线上有没有皇后 
int cnt=0;//记录多少种放法 
int main()
{
	dfs(0);
	cout<<cnt;
	return 0;
}
void dfs(int count)//寻找第count行 皇后的位置 
{
	int i,j,k;
	if(count==8){//当八个皇后都排好时 输出 
		cnt++;
		for(i=0;i<8;i++){
			for(j=0;j<8;j++){
				if(q[i][j]==1){
					cout<<'#';//皇后的位置输出'#' 
				}
				else{
					cout<<'0';
				}
			}
			cout<<'\n';
		}
		cout<<"--------------------\n";
		return ;
	}
	for(i=0;i<8;i++){
		if(c[i]==0){//当这一列没有皇后时 再进入判断 
			if(judge(count,i)){//当斜线方向也没有皇后时 
				q[count][i] = 1;//记录位置 
				c[i] = 1;
				dfs(count+1);//进入下一行 
				q[count][i]=0;//如果从dfs(count+1)出来后要对第count行的第i+1列进行判断 所以 c[i] = 0;q[count][i]=0;
				c[i] = 0;
			}
		}
	}
}
 
bool judge(int row,int col)
{
	int i=1,j,k;
	if(c[col]){
		return false;
	}
	while((--row)>=0){
		//row--;
		if(col+i<8){
			if(q[row][col+i]){
				return false;
			}
		}
		if(col-i>=0){
			if(q[row][col-i]){
				return false;
			}
		}
		i++;
	}
	return true;
}

//用一维数组表示 c[i] = j 第i行的第j个元素是皇后  
#include<iostream>
using namespace std;
int c[9],cnt=0; 
void dfs(int count);
bool judge(int row,int col);
int main(){
	dfs(1);
	cout<<cnt;
	return 0;
}
void dfs(int count)
{
	int i,j,k;
	if(count==9){
		for(i=1;i<=8;i++){
			for(j=1;j<=8;j++){
				if(c[i]==j){
					cout<<"$";
				}
				else{
					cout<<"0";
				}
			}
			cout<<endl;
		}
		cout<<endl;
		cnt++;
	}
	for(i=1;i<=8;i++){//舍弃第一个 让零作为一个标志位 
		if(judge(count,i)){
			c[count] = i;
			dfs(count+1);
			c[count] = 0;
		}
	}
}
bool judge(int row,int col)
{
	int i,j,k;
	for(i=1;i<row;i++){//检查同一列 
		if(c[i]==col){
			return false;
		}
	}
	for(i=1;i<row;i++){//检查两个斜线方向 
		if(c[row-i] == col-i || c[row-i]==col+i){
			return false;
		}
	} 
	return true;
}

//用回溯写
#include<iostream>
using namespace std;
int c[9],cnt=0;
bool judge(int row,int col);
void print();
int main()
{
	int i,j,k;
	k = 1;
	c[k] = 0;
	while(k>0){
		c[k] += 1;
		while(c[k]<=8 && !judge(k,c[k])){//如果这一列不符合条件 就看下一列 
			c[k]+=1;
		}
		if(c[k]<=8){//如果这一行中有皇后 
			if(k==8){//如果到了第八行 说明全部完成  
				print();
				cnt++;
				c[k] = 0;
				k--; //回溯到上一行并且这一行的皇后复位为0
			}
			else{
				k++;//看下一行 
				c[k] = 0;
			}
		}
		else{//未找到 则回溯到上一行 
			c[k] = 0;//复位为0 
			k--;//回溯到上一行 
		}
	}
	cout<<cnt;
	return 0;	
} 
bool judge(int row,int col)
{
	int i,j,k;
	for(i=1;i<row;i++){
		if(c[i]==col){
			return false;
		}
	}
	for(i=1;i<row;i++){
		if(c[row-i] == col-i || c[row-i]==col+i){
			return false;
		}
	} 
	return true;
}
void print()
{
	for(int i=1;i<=8;i++){
		for(int j=1;j<=8;j++){
			if(c[i]==j){
				cout<<"$";
			}
			else{
				cout<<"0";
			}
		}
		cout<<endl;
	}
	cout<<endl;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值