八皇后问题 回溯

来源:互联网 发布:ios文件上传java 接口 编辑:程序博客网 时间:2024/05/21 06:17

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

*该问题是十九世纪著名的数学家高斯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;} 


0 0
原创粉丝点击