006回溯法——n皇后问题

来源:互联网 发布:淘宝店铺自助服务在哪 编辑:程序博客网 时间:2024/06/17 18:45

     在n×n格的棋盘上放置彼此不受攻击的n个皇后。按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。n后问题等价于在n×n格的棋盘上放置n个皇后,任何2个皇后不放在同一行或同一列或同一斜线上。

     代码如下:

//nQueen//by xcz on 2013.9.10#include <iostream>#include "math.h"using namespace std;//记录解空间的节点信息class Queen{friend int nQueen(int);private:bool Place(int k);void Backtrack(int t);int n,//皇后的个数*x;//n元组x[1:n]表示n后问题的解,其中,x[i]表示皇后i放在棋盘的第i行的第x[i]列,两两要互不相等;long sum;//可行解数量};//检测解的可行性,剪枝函数bool Queen::Place(int k){for (int j=1 ; j<k ; ++j){if((abs(k-j)==abs(x[j]-x[k]))||(x[j]==x[k]))//判断斜线有没有皇后,其斜线斜率为+1,-1,或者看其下标之差或者之和是否相等return false;                               //后面是判断是否在同一列}return true;}//采用递归回溯遍历解空间树,解空间树为子集树void Queen::Backtrack(int t){if (t>n){sum++;//t为解空间层数,当搜索到n以后,说明解可行for (int i=1 ;i<=n ; ++i){cout<<x[i]<<" ";}cout<<endl;}elsefor (int i=1 ; i<=n ;++i){x[t] =i;if(Place(t))Backtrack(t+1);}}int nQueen(int n){Queen X;//初始化XX.n = n;X.sum = 0;int *p = new int[n+1];for (int i=0 ; i<=n ; ++i)p[i]=0;X.x=p;X.Backtrack(1);delete []p;return X.sum;}int main(){int n=8,ans;cout<<n<<"皇后问题的解为:"<<endl;ans = nQueen(n);cout<<n<<"皇后问题共有"<<ans<<"个不同的解"<<endl;system("pause");return 0;}

另:今天是教师节,祝那些可敬的老师们节日快乐,另外还要感谢csdn无私的博主们,以及百度 and google~~