八皇后问题 回溯

八皇后问题是一个古老而著名的问题,是回溯算法的典型例题。

*该问题是十九世纪著名的数学家高斯1850年提出:在8X8格的国际象棋上摆放八个皇后,

*使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,


思路:需要一个长度为8的一维数组。数组下标表示行,数组值表示列。那么如何检查是否在同一斜线呢。只要斜率为1或者-1.即数组值相减和数组下标相减的值相等,或者为相反数。对每产生一个新的皇后,都要检查是否与前面的皇后冲突。所以理解了还是很简单的。

//自己根据之前的用标记,来写的!对了!
//看来这题和全排列其实差不多。 
#include<cstdio>
int a[8],count;
int v[8]={0};
void print(){
	for(int i=0;i<8;i++){
		printf("%d%c",a[i],i==7?'\n':' ');
	}
}
bool check(int i){
	for(int j=0;j<i;j++){
		if(v[a[i]]||a[i]-a[j]==i-j||a[j]-a[i]==i-j) return false;
	}
	return true;
}
void fun(int n){//在循环中使用递归,此刻考察的是第n个皇后! 
	if(n==8){
		print();
		count++;
		return; 
	}
	for(int i=0;i<8;i++){//想一想全排列。并且排除已经排在队列中的 
		a[n]=i;
		if(check(n)){//与全排列的差别只是这里的check函数复杂一些 
			v[i]=1;
			fun(n+1);
			v[i]=0;	
		}
}
} 
int main(){
	//for(int i=0)
	fun(0);
	printf("%d",count);
	return 0;
} 

人家的方法

//打印了中间结果,最后答案92,ac 
#include<cstdio>
int a[8],count;
int v[8];
void print(){
	for(int i=0;i<8;i++){
		printf("%d%c",a[i],i==7?'\n':' ');
	}
}
bool check(int i){
	for(int j=0;j<i;j++){
		if(a[i]==a[j]||a[i]-a[j]==i-j||a[j]-a[i]==i-j) return false;
	}
	return true;
}
void fun(int n){//在循环中使用递归,此刻考察的是第n个皇后! 
	if(n==8){
		print();
		count++;
		return; 
	}
	for(int i=0;i<8;i++){
		a[n]=i;
		if(check(n)){//如果循环到的这个位置符合,那么就考察下一个皇后的位置啊! 
			fun(n+1);	
		}
}
} 
int main(){
	//for(int i=0)
	fun(0);
	printf("%d",count);
	return 0;
} 


你可能感兴趣的:(递归,八皇后,回溯)