[我与八皇后的恩恩怨怨]满足行条件的全排列,然后一一检测是否满足八皇后即可(全排列解法)

什么是八皇后

八皇后问题是一个古老而著名的问题,是回溯算法的典型例题。该问题是十九世纪著名的数学家高斯1850年提出:在8X8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法?

高斯认为有76种方案。1854年在柏林的象棋杂志上不同的作者发表了40种不同的解,后来有人用图论的方法解出92种结果。(程序跑出来也的确是92种)

八皇后的解法很多

今天,我们只用全排列

代码不长,思路也简单。
首先,八皇后肯定是每行都有,并且都不同列,我们可以通过这个的全排列,来检查是否满足八皇后即可
所以,1,2,3,4,5,6,7,8的全排列,一定是包含了八皇后的解的。
那么我们一一检测就可以得出结果了!

代码如下:
竟然还写的一大会儿,我还是太菜了!
看的人多,我再写其他的解法T.T!!!

#include<iostream>
#include<algorithm>
#include<cstring>
#define mm(a,b) memset(a,b,sizeof(a))
using namespace std;
int ans=0;
void print(int map[][8]){
	for(int i=0;i<8;i++){
		for(int j=0;j<8;j++){
			if(map[i][j]==0) cout<<"#"<<" ";
			else             cout<<"0"<<" ";
		}
		cout<<endl;
	}
}
void search(int map[][8]){
	int cntx=0,cnty=0;
	for(int i=0;i<8;i++){
		for(int j=0;j<8;j++){
			if(map[i][j]==1) cntx++;
			if(map[j][i]==1) cnty++;
			if(cntx>1||cnty>1) return ;	
		}
		cntx=0;
		cnty=0;
	}
	for(int i=0;i<8;i++){
		int cnt=0;
		int j=0;
		int tempi=i;
		while(tempi<8&&j<8){
			if(map[tempi][j]==1) cnt++;
			if(cnt>1) return ;
			tempi++;
			j++;
		}
		tempi=i,j=0,cnt=0;
		while(tempi>=0&&j<8){
			if(map[tempi][j]==1) cnt++;
			if(cnt>1) return ;
			tempi--;
			j++;
		}
	}
	for(int j=1;j<8;j++){
		int cnt=0;
		int i=0;
		int tempj=j;
		while(i<8&&tempj<8){
			if(map[i][tempj]==1) cnt++;
			if(cnt>1) return ;
			tempj++;
			i++;
		}	
		cnt=0,i=7,cnt=0;
		tempj=j;
		while(i>=0&&tempj<8){
			if(map[i][tempj]==1) cnt++;
			if(cnt>1) return ;
			tempj++;
			i--;
		}	
	}
	ans++;
	cout<<endl<<"第"<<ans<<"种解法:"<<endl; 
	print(map);
	return ;
}
int main(){
	int num[8]={1,2,3,4,5,6,7,8};
	int map[8][8];
	do{
		mm(map,0); 
		for(int i=0;i<8;i++){
			map[i][num[i]-1]=1;
		}
		search(map);
	}while(next_permutation(num,num+8));
	cout<<"八皇后问题共有"<<ans<<"种解法!"<<endl;
	return 0;
}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值