n皇后问题
第2讲 搜索算法-N皇后问题的自动求解
8
N皇后问题的解之间有什么关联?这些解有什 么特点? N皇后问题的解的个数跟N有关系吗?
N 1 2 3 4 5 6 7 8 9 10 解的个数 1 0 0 2 10 4 40 92 352 724
9
思考2:如何理解对角线
N皇后中的对角线,以8皇后问题为例。主对角线 一共有15条。我们将这种对角线称为第1种情形的 对角线。
void CNQueenDlg::OnLButtonDown(UINT nFlags, CPoint point) { //代码有点缺陷:没有判定单击位置是否已经超出棋盘范围 int c = (point.x-20)/cell, r = (point.y-20)/cell; queen[r][c] = 1 - queen[r][c]; RECT rect; rect.left = 20+c*cell, rect.top = 20+r*cell; rect.right = 20+(c+1)*cell, rect.bottom = 20+(r+1)*cell; InvalidateRect( &rect ); //只刷新鼠标单击位置所在的方格 CDialog::OnLButtonDown(nFlags, point); }
3
8皇后问题
N=8时,N皇后问 题就成了经典的8 皇后问题。 8皇后问题:要在 8×8大小的棋盘上 放置8个皇后,使 得任意两个皇后不 在同一行、同一列, 以及对角线上。
4
8皇后问题的演示
数据结构与算法演示软件
数据结构算法|栈和队列|递归过程|皇后问题(注意观察 回退过程)
5
8皇后问题的一个解
6
思考1:N皇后问题解的个数
回溯法实验(n皇后问题)(迭代法)
算法分析与设计实验报告第三次附加实验附录:完整代码(回溯法)//回溯算法递归回溯n皇后问题#include<iostream>#include<time.h>#include<iomanip>#include"math.h"using namespace std;class Queen{friend int nQueen(int); //定义友元函数,可以访问私有数据private:bool Place(int k); //判断该位置是否可用的函数void Backtrack(int t); //定义回溯函数int n; //皇后个数int *x; //当前解long sum; //当前已找到的可行方案数};int main(){int m,n;for(int i=1;i<=1;i++){cout<<"请输入皇后的个数:"; //输入皇后个数cin>>n;cout<<"皇后问题的解为:"<<endl;clock_t start,end,over; //计算程序运行时间的算法start=clock();end=clock();over=end-start;start=clock();m=nQueen(n); //调用求解的函数cout<<n<<"皇后问题共有";cout<<m<<"个不同的解!"<<endl; //输出结果end=clock();printf("The time is %6.3f",(double)(end-start-over)/CLK_TCK); //显示运行时间cout<<endl;}system("pause");return 0;}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]))//如果两个在同一斜线或者在同一列上,说明冲突,该位置不可用{return false;}}return true;}void Queen::Backtrack(int t){if(t>n){sum++;/*for(int i=1;i<=n;i++) //输出皇后排列的解{cout<<x[i]<<" ";}cout<<endl;*/}else{//回溯探索第i行的每一列是否有元素满足要求for(int i=1;i<=n;i++){x[t]=i;if(Place(t)){Backtrack(t+1);}}}}int nQueen(int n){Queen X; //定义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;//输出解的个数}完整代码(回溯法)//回溯算法迭代回溯n皇后问题#include<iostream>#include<time.h>#include<iomanip>#include"math.h"using namespace std;class Queen{friend int nQueen(int); //定义友元函数private:bool Place(int k); //定义位置是否可用的判断函数void Backtrack(void); //定义回溯函数int n; // 皇后个数int *x; // 当前解long sum; // 当前已找到的可行方案数};int main(){int n,m;for(int i=1;i<=1;i++){cout<<"请输入皇后的个数:";cin>>n;cout<<n<<"皇后问题的解为:"<<endl;clock_t start,end,over; //计算程序运行时间的算法start=clock();end=clock();over=end-start;start=clock();m=nQueen(n); //调用求解皇后问题的函数cout<<n<<"皇后问题共有";cout<<m<<"个不同的解!"<<endl;end=clock();printf("The time is %6.3f",(double)(end-start-over)/CLK_TCK); //显示运行时间cout<<endl;}system("pause");return 0;}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])) //如果两个皇后在同一斜线或者在同一列上,说明冲突,该位置不可用{return false;}}return true;}void Queen::Backtrack() //迭代法实现回溯函数{x[1] = 0;int k = 1;while(k>0){x[k] += 1; //先将皇后放在第一列的位置上while((x[k]<=n)&&!(Place(k))) //寻找能够放置皇后的位置{x[k] += 1;}if(x[k]<=n) //找到位置{if(k == n) //如果寻找结束输出结果{/*for (int i=1;i<=n;i++){cout<<x[i]<<" ";}cout<<endl; */sum++;}else//没有结束则找下一行{k++;x[k]=0;}}else//没有找到合适的位置则回溯{ k--; }}}int nQueen(int n){Queen X; //定义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();delete []p;return X.sum; //返回不同解的个数}。
用遗传算法解决n皇后问题
用遗传算法解决n皇后问题(李怀远)一、问題提出N皇后问题描述如下:在nxn格棋盘上敖置彼此不受攻击的n个皇后。
按国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。
N皇后问题等价于在以下三个约束条件下:约束①任何2个皇后不放在同一行;约束②任何2个皇后不放在同一列;约束③任何2个皇后不放在同斜线;找出一种合法的放置方案。
我们把nxn的棋盘看作二维方阵,其行号从上到下列号从左到右依次编号为0, 1,…, n-l.。
设任意两个皇后,皇后1和皇后2的坐标分别是(i.j)和(k,l),则如果这两个皇后在从棋盘左上角到右下角的主对角线及其平行线(斜率为-1的线)上,有i-j=k-l=0 ;如果这两个皇后在斜率为+ 1的每一斜线上,有i+j=k+l;以上两个方程分别等价于i-k=j-l 和i-k=l-j因此任两皇后的在同一斜线上的充要条件是l/-^l=l J-/I 式①因此满足两个皇后不在同一斜线上的条件表示为:\i-kM j-l\式②两皇后不在同一行用式表示为:iHk式③两皇后不在同一列用式表示为:j^l式④此属NP问题不易求解,现在我们把任意n个皇后的任意一种放置办法当作一个个体(染色体),把其中的任意一个皇后当作一个基因,用遗传算法来解决该问題。
二、编码方案对于此问题我提出两种编码方案。
A.编码方案1:排列编码用一维n元数组x[0:n-l]来表示一个个体,其中x[i]e{0,l,…,n-1}, x[i]表示皇后i放在棋盘的第i行第x[i]列,即第i行第x[i]列放置一个皇后。
例如,x[0]=0 表示棋盘的第0行第0列敖一个皇后。
数组第i个元素表示第i行的放置情况,可以看作一个基因。
这种编码可以自然的解决了某一行只能放一个皇后的约束,如果数组的每一个元素x[i]都不重复,可以看成0——n-l的一种排列,就自然保证每一列只能放一个皇后。
因此在交叉变异和产生个体时必须注意x[i]的唯一性。
N皇后问题
n皇后问题【问题描述】在n×n的国际象棋盘上,放置n个皇后,使任何一个皇后都不能吃掉另一个,需满足的条件是:同一行、同一列、同一对角线上只能有一个皇后。
求所有满足要求的放置方案。
【输入】一个正整数n,表示皇后的个数。
【输出】每行代表一种放置方案:第i行的第一个数是i,表示第i种方案,后面一个冒号,然后是用空格隔开的n个数,其中第i个数x[i]表示第i行上的皇后放在第x[i]列;最后一行:一个整数,表示方案总数。
〖问题描述〗在一个8×8的棋盘里放置8个皇后,要求每个皇后两两之间不相"冲"(在每一横列竖列斜列只有一个皇后)。
〖问题分析〗(聿怀中学吕思博)这道题可以用递归循环来做,分别一一测试每一种摆法,直到得出正确的答案。
主要解决以下几个问题:1、冲突。
包括行、列、两条对角线:(1)列:规定每一列放一个皇后,不会造成列上的冲突;(2)行:当第I行被某个皇后占领后,则同一行上的所有空格都不能再放皇后,要把以I 为下标的标记置为被占领状态;(3)对角线:对角线有两个方向。
在同一对角线上的所有点(设下标为(i,j)),要么(i+j)是常数,要么(i-j)是常数。
因此,当第I个皇后占领了第J列后,要同时把以(i+j)、(i-j)为下标的标记置为被占领状态。
2、数据结构。
(1)解数组A。
A[I]表示第I个皇后放置的列;范围:1..8(2)行冲突标记数组B。
B[I]=0表示第I行空闲;B[I]=1表示第I行被占领;范围:1..8 (3)对角线冲突标记数组C、D。
C[I-J]=0表示第(I-J)条对角线空闲;C[I-J]=1表示第(I-J)条对角线被占领;范围:-7..7 D[I+J]=0表示第(I+J)条对角线空闲;D[I+J]=1表示第(I+J)条对角线被占领;范围:2..16〖算法流程〗1、数据初始化。
2、从n列开始摆放第n个皇后(因为这样便可以符合每一竖列一个皇后的要求),先测试当前位置(n,m)是否等于0(未被占领):如果是,摆放第n个皇后,并宣布占领(记得要横列竖列斜列一起来哦),接着进行递归;如果不是,测试下一个位置(n,m+1),但是如果当n<=8,m=8时,却发现此时已经无法摆放时,便要进行回溯。
N皇后问题及答案解
N皇后问题及答案解题⽬在⼀张N∗N的国际象棋棋盘上,放置N个皇后,使得所有皇后都⽆法互相直接攻击得到,(皇后可以直接攻击到她所在的横⾏,竖列,斜⽅向上的棋⼦),现在输⼊⼀个整数N,表⽰在N∗N的棋盘上放N个皇后,请输出共有多少种使得所有皇后都⽆法互相直接攻击得到的⽅案数。
例如下⾯这样的摆法,是4皇后的⼀个解 (1代表有皇后,0代表没有)0 1 0 00 0 0 11 0 0 00 0 1 0输⼊⼀个整数N,代表皇后的个数输出输出⽅案数样例输⼊样例输⼊14样例输⼊28样例输出样例输出12样例输出292⼀、DFS+回溯(1)设已经放好的皇后坐标为(i,j),待放⼊的皇后坐标为(r,c),则它们满⾜以下关系:(1)不同⾏,即 i ≠ r;(2)不同列,即 j ≠ c;(3)不在斜对⾓线上,即 |i-r| ≠ |j-c|.可以在⼀⾏逐列尝试,这样就不⽤考虑(1)了。
#include <iostream>#include <algorithm>#include <cstring>using namespace std;int n, tot = 0;int col[15] = {0}, ans[15] = {0}; //col[i]的值为第i⾏的皇后的列数的值,即j,ans[]数组⽤来存放结果bool check(int c, int r) //检查是否和已经放好的皇后冲突{for (int i = 0; i < r; i++)if (col[i] == c || (abs(col[i] - c) == abs(i - r))) //因为是逐⾏放置,所以只考虑纵向和斜向return false;return true;}void dfs(int r,int m) //在第r⾏放皇后,m表⽰⾏数{if(r==m){ //r==m,即皇后放到最后⼀⾏,满⾜条件,tot++,返回;tot++;return;}for(int c=0;c<m;c++) //在此⾏逐列尝试if(check(c,r)){ //检查是否冲突col[r]=c; //不冲突就在此列放皇后dfs(r+1,m); //转到下⼀⾏继续尝试}}int main(){cin>>n;for (int i = 0; i <= 13; i++) //算出所有N皇后的答案,先打表,不然会超时{memset(col, 0, sizeof(col)); //清空col,准备计算下⼀个N皇后问题tot = 0;dfs(0,i);ans[i] = tot;}cout << ans[n] << endl;return 0;}在上述程序中,dfs()⼀⾏⾏放置皇后,时间复杂度为O(N!);check()判断冲突,时间复杂度为O(N),总的为O(N*N!)!⾮常的⾼。
n皇后问题递归算法c语言
n皇后问题递归算法c语言概述n皇后问题是一个经典的回溯算法问题,它要求在一个n×n的棋盘上放置n个皇后,使得它们互不攻击。
本文将使用递归算法来解决n皇后问题,并使用C语言进行实现。
问题描述在n×n的棋盘上放置n个皇后,使得它们不在同一行、同一列或同一斜线上。
其中,皇后的移动规则是可以横向、纵向、对角线方向上自由移动任意步数。
算法思路为了解决n皇后问题,我们可以采用递归的方式逐行放置皇后。
具体地,可以按照行优先的顺序,从第一行开始放置皇后,并逐行向下递归,直到放置了n个皇后,或者无法再放置皇后为止。
算法的关键在于如何判断当前位置是否可以放置皇后,即判断是否与已经放置的皇后位置冲突。
为了判断冲突,我们需要考虑以下几个方面:1.所有皇后不能在同一列:我们可以使用一个数组q ue en[]来记录每一行放置的皇后的列位置。
2.所有皇后不能在同一对角线上:我们可以使用两个数组up D ia g[]和d ow nD ia g[]来记录每一条对角线上是否已经存在皇后。
对于任意一个位置(i,j),它所在的主对角线上的元素满足i-j的值相等,次对角线上的元素满足i+j的值相等。
在放置皇后时,我们可以逐个尝试每一列,然后检查当前位置是否与已经放置的皇后位置冲突,如果冲突则继续尝试下一列,直到找到一个合适的位置。
然后,继续递归放置下一行的皇后,直到放置了n个皇后或者无法再放置为止。
伪代码定义一个全局整型数组q ue en[],用于记录每一行放置的皇后的列位置定义两个全局整型数组u pD ia g[]和do wn D ia g[],用于记录每一条对角线上是否已经存在皇后P r oc ed ur en Qu ee ns(r ow):i f ro w=n://找到一个解P r in tS ol ut io n()r e tu rnf o rc ol fr om0t on-1:i f Ca nP la ce Qu ee n(r o w,co l):P l ac eQ ue en(r ow,co l)n Q ue en s(ro w+1)R e mo ve Qu ee n(ro w,c o l)P r oc ed ur eC an Pl ace Q ue en(r ow,c ol):i f qu ee n[co l]!=-1:r e tu rn fa ls ei f up Di ag[r ow-c ol+n-1]!=-1o rd ow nDi a g[ro w+co l]!=-1:r e tu rn fa ls er e tu rn tr ueP r oc ed ur eP la ce Que e n(ro w,co l):q u ee n[co l]=r owu p Di ag[r ow-c ol+n-1]=1d o wn Di ag[r ow+c ol]=1q u ee n[co l]=-1u p Di ag[r ow-c ol+n-1]=-1d o wn Di ag[r ow+c ol]=-1P r oc ed u r eP ri nt Sol u ti on():f o rr ow fr om0t on-1:f o rc ol fr om0t on-1:i f qu ee n[co l]=r ow:p r in t"Q"e l se:p r in t"*"p r in tn ew li nep r in tn ew li neC语言实现下面是使用C语言实现的n皇后问题递归算法的代码示例:#i nc lu de<s td io.h>#d ef in eN8i n tq ue en[N];//记录每一行放置的皇后的列位置i n tu pD ia g[2*N-1];//记录每一条对角线上是否已经存在皇后i n td ow nD ia g[2*N-1];//记录每一条对角线上是否已经存在皇后v o id nQ ue en s(in tro w);i n tc an Pl ac eQ ue en(i nt ro w,in tc ol);v o id pl ac eQ ue en(in t ro w,in tc ol);v o id pr in tS ol ut ion();i n tm ai n(){f o r(in ti=0;i<N;i++){q u ee n[i]=-1;}f o r(in ti=0;i<2*N-1;i++){u p Di ag[i]=-1;d o wn Di ag[i]=-1;}n Q ue en s(0);r e tu rn0;}v o id nQ ue en s(in tro w){i f(r ow==N){p r in tS ol ut io n();r e tu rn;}f o r(in tc ol=0;c ol<N;c ol++){ i f(c an Pl ac eQ ue en(r ow,c ol)){ p l ac eQ ue en(r ow,co l);n Q ue en s(ro w+1);r e mo ve Qu ee n(ro w,c o l);}}}i n tc an Pl ac eQ ue en(i nt r o w,in tc ol){i f(q ue en[c ol]!=-1){r e tu rn0;}i f(u pD ia g[ro w-col+N-1]!=-1||do wnD i ag[r ow+c ol]!=-1){ r e tu rn0;}r e tu rn1;}v o id pl ac eQ ue en(in t ro w,in tc ol){q u ee n[co l]=r ow;u p Di ag[r ow-c ol+N-1]=1;d o wn Di ag[r ow+c ol]=1;}v o id re mo ve Qu ee n(i n tr ow,i nt co l){q u ee n[co l]=-1;u p Di ag[r ow-c ol+N-1]=-1;d o wn Di ag[r ow+c ol]=-1;}v o id pr in tS ol ut ion(){f o r(in tr ow=0;r ow<N;r ow++){f o r(in tc ol=0;c ol<N;c ol++){i f(q ue en[c ol]==ro w){p r in tf("Q");}e ls e{p r in tf("*");}}p r in tf("\n");}p r in tf("\n");}总结本文使用C语言实现了n皇后问题的递归算法。
n皇后问题课程设计
n皇后问题课程设计一、教学目标本节课的教学目标是让学生掌握“N皇后问题”的解决方法,理解其背后的数学原理和计算机科学应用。
知识目标要求学生了解“N皇后问题”的定义、解法和优化策略;技能目标要求学生能够运用所学的知识解决实际问题,编写出相应的算法程序;情感态度价值观目标则是培养学生对计算机科学的兴趣,提高其创新意识和解决问题的能力。
二、教学内容本节课的教学内容主要包括三个部分:第一部分是“N皇后问题”的定义和基本解法,让学生了解问题背景和基本概念;第二部分是“N皇后问题”的优化策略,让学生掌握如何提高算法效率;第三部分是“N皇后问题”的计算机编程实践,让学生亲自动手编写程序,巩固所学知识。
三、教学方法为了达到本节课的教学目标,我们将采用以下教学方法:首先,通过讲授法向学生介绍“N皇后问题”的基本概念和解法;其次,运用讨论法让学生分组讨论优化策略,促进学生思考;然后,采用案例分析法分析实际问题,引导学生将所学知识应用于实践;最后,通过实验法让学生动手编程,培养其实际操作能力。
四、教学资源为了支持本节课的教学内容和教学方法,我们将准备以下教学资源:首先,教材和参考书,为学生提供理论支持;其次,多媒体资料,如课件、视频等,帮助学生形象理解问题;再次,实验设备,如计算机等,让学生进行编程实践;最后,网络资源,如在线编程平台等,为学生提供更多学习资源和交流渠道。
五、教学评估为了全面、客观地评估学生在“N皇后问题”课程中的学习成果,我们将采取以下评估方式:1.平时表现:通过课堂参与、提问、回答问题等方式评估学生的学习态度和理解程度,占总评的30%。
2.作业:布置与课程相关的中等难度练习题,要求学生在规定时间内完成,占总评的20%。
3.实验报告:学生在实验过程中独立编写程序,并撰写实验报告,占总评的20%。
4.期末考试:期末考试中将包含“N皇后问题”的相关题目,测试学生对该课程知识的掌握程度,占总评的30%。
六、教学安排本课程的教学安排如下:1.授课时间:共8课时,每课时45分钟。
n皇后问题
n 后问题1 问题描述:N 皇后问题是一个古老而著名的问题。
该问题是十九世纪著名的数学家高斯1850年提出的。
八皇后问题要求在一个N *N 的棋盘上放上N 个皇后,使得每一个皇后既攻击不到另外N-1个皇后,也不被另外N-1个皇后所攻击.按照国际象棋的规则,一个皇后可以攻击与之处在同一行或同一列或同一斜线上的其他任何棋子,问有多少种不同的摆法?并找出所有的摆法。
因此,N 皇后问题等于要求N 个皇后中的任意两个不能被放在同一行或同一列或同一斜线上。
2 回朔法回溯法有“通用的题解法”之称。
从问题的某种可能情况出发,搜索所有能到达的可能情况,然后以其中一种可能的情况为新的出发点,继续向下探索,当所有可能情况1 2 3 4 5 6 7 8 1 2 3 4 5 6 78都探索过且都无法到达目标的时候,再回退到上一个出发点,继续探索另一个可能情况,这种不断回头寻找目标的方法称为“回溯法”。
适用于解组合是较大的问题。
回朔法思想:1针对所给问题,定义问题的解空间。
2.确定易于搜索的解空间结构。
3.以深度优先的方式搜索解空间,并且在搜索过程中用剪枝函数避免无效搜索。
在搜索过程中,通常采用两种策略避免无效搜索:一是用约束函数剪去得不到可行解的子树;二是用限界函数剪去得不到最优解的子树。
这两类函数统称为剪枝函数。
回溯算法的一个显著的特性是在搜索过程中动态产生问题的解空间。
在任何时刻,只保存从根结点到当前扩展结点的路径。
因此,回溯算法的空间需求为o(n),(n为从根结点起最长路径的长度)。
而显式地存储整个解空间则需要o(2n)或o(n!)内存空间。
回溯法对解空间作深度优先搜索,因此,在一般情况下用递归方法实现回溯法。
void backtrack (int t){if (t>n) output(x);elsefor (int i=f(n,t);i<=g(n,t);i++){x[t]=h(i);if (constraint(t)&&bound(t)) backtrack(t+1);}}采用树的非递归深度优先遍历算法,可将回溯法表示为一个非递归迭代过程。
n后问题-回溯法
n后问题-回溯法问题描述: 在n*n的棋盘上放置彼此不受攻击的n个皇后。
按国际象棋的规则,皇后可以与之处在同⼀⾏或者同⼀列或同⼀斜线上的棋⼦。
n后问题等价于在n*n格的棋盘上放置n皇后,任何2个皇后不放在同⼀⾏或同⼀列的斜线上。
算法设计: |i-k|=|j-l|成⽴,就说明2个皇后在同⼀条斜线上。
可以设计⼀个place函数,测试是否满⾜这个条件。
1 当i>n时,算法搜索⾄叶节点,得到⼀个新的n皇后互不攻击放置⽅案,当前已找到的可⾏⽅案sum加1. 2 当i<=n时,当前扩展结点Z是解空间中的内部结点。
该结点有x[i]=1,2,3....n共n个⼉⼦节点。
对当前扩展结点Z的每个⼉⼦节点,由place检察其可⾏性。
并以深度优先的⽅式递归地对可⾏⼦树,或剪去不可⾏⼦树。
算法描述: #include <iostream>#include <cstdlib>using namespace std;class Queen{friend int nQueen(int);private:bool Place(int k);void Backtrack(int t);int n,* x;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]))return false;return true;}void Queen::Backtrack(int t){if(t>n)sum++;elsefor(int i=1;i<=n;i++){x[t] = i;if(Place(t))Backtrack(t+1);}}int nQueen(int n){Queen X;X.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;cout<<X.sum<<endl;return X.sum;}int main(){nQueen(4);nQueen(2);nQueen(3);return0;}执⾏结果:迭代回溯:数组x记录了解空间树中从根到当前扩展结点的路径,这些信息已包含了回溯法在回溯时所需要的信息。
N皇后问题及深度优先算法
常规N皇后解决问题过程一.问题描述运用回溯法解题通常包含以下三个步骤:(1)针对所给问题,定义问题的解空间;(2)确定易于搜索的解空间结构;(3)以深度优先的方式搜索解空间,并且在搜索过程中用剪枝函数避免无效搜索;通过上述的基本思路,我们可以将问题描述为:X(j)表示一个解的空间,j表示行数,里面的值表示可以放置在的列数,抽象约束条件得到能放置一个皇后的约束条件(1)X(i)!=X(k);(2)abs(X(i)-X(k))!=abs(i-k)。
应用回溯法,当可以放置皇后时就继续到下一行,不行的话就返回到第一行,重新检验要放的列数,如此反复,直到将所有解解出。
也就是对于N×N的棋盘,选择出N个符合i!=r∧j!=s∧|i-r|!=|j-s|∨(i+r)!=(j+s)的点的排列总数。
二.伪代码:判断点是否符合要求:place(k, X)I=1While i<k doIf x[i]==x[k] orabs(x[i]-x[k])==abs(i-k) thenReturn falseI=i+1Return true求问题的所有解:Nqueens(n, X)Sum=0 , X[1]=0 , k=1While k>0 doX[k]=X[k]+1While X[k]<=n and !(place(k,x))X[k]=X[k]+1If X[k]<=n thenSum=Sum+1ElseK=K+1 ,X[k]=0ElseK=K-1Print sum三.代码实现#include <iostream>using namespace std;#include <math.h>/*检查可不可以放置一个新的皇后*/ bool place(int k, int *X){int i;i=1;while(i<k){if((X[i]==X[k])||(abs(X[i]-X[k] )==abs(i-k)))return false;i++;}return true;}/*求解问题的所有解的总数,X存放列数*/ void Nqueens(int n,int *X){int k,sum=0;X[1]=0;k=1;while(k>0){X[k]=X[k]+1;while((X[k]<=n)&&(!place(k, X)))X[k]=X[k]+1;if(X[k]<=n)if(k==n){for(int i=1;i<=n;i++)cout<<X[i]<<" ";cout<<endl;sum++;}else{k=k+1;X[k]=0;}elsek=k-1;}cout<<"解的总数为:"<<sum<<endl;}int main(){int n;int *X;cout<<"请输入皇后的个数:";cin>>n;X=new int[n];cout<<"问题的解如下:"<<endl;Nqueens(n,X);return 0;}五.存在的问题当皇后个数N大于等于16以上,程序对棋盘的扫描次数大到惊人:从维基百科列出的结果不难看出,在25皇后时,符合条件的解集已经如此庞大了。
一种求解n皇后问题的概率回溯复合算法
n皇后问题是一种经典的搜索问题,它的目标是在n*n的棋盘上放置n个皇后,使得这n 个皇后互不攻击(不在同一行、同一列、同一对角线上)。
求解n皇后问题的概率回溯复合算法是一种搜索算法,它通过在回溯过程中加入概率元素,来提高求解n皇后问题的效率。
具体来说,该算法的基本思路是:
初始化:将棋盘初始化为一个n*n的空棋盘,并设置一个计数器count,用于记录已经放置的皇后的数量。
回溯:从第0行开始,依次枚举每一行的每一列,判断是否可以在该位置放置皇后。
如果可以,就在该位置放置皇后,并将计数器count加1。
如果不可以,就跳过该位置,继续枚举下一列。
概率元素:在枚举每一列时,随机生成一个概率值p(0<=p<=1)。
如果p大于0.5,则在该位置放置皇后;否则跳过该位置,继续枚举下一列。
这样,在回溯过程中加入了一定的随机性,使得算法具有一定的概率元素。
终止条件:如果count的值等于n,则说明已经成功放置了n个皇后,可以终止算法。
否则,继续执行下一行的枚举过程。
复合:在每一行枚举完所有列之后,需要将已经放置的皇后撤销,并将计数器count减1,然后回到上一行,继续枚举下一列。
这样,在回溯的过程中,算法会不断地撤销和放置皇后,从而实现复合的效果。
总之,求解n皇后问题的概率回溯复合算法是一种结合了回溯和概率元素的搜索算法,可以有效地提高求解n皇后问题的效率。
n皇后问题
问题描述:求出在一个n×n的棋盘上,放置n个不能互相捕捉的国际象棋“皇后”的所有布局。
这是来源于国际象棋的一个问题。
皇后可以沿着纵横和两条斜线4个方向相互捕捉。
如图所示,一个皇后放在棋盘的第4行第3列位置上,则棋盘上凡打“×”的位置上的皇后就能与这个皇后相互捕捉。
1 2 3 4 5 6 7 8×××××××××× Q ×××××××××××××××从图中可以得到以下启示:一个合适的解应是在每列、每行上只有一个皇后,且一条斜线上也只有一个皇后。
求解过程从空配置开始。
在第1列至第m列为合理配置的基础上,再配置第m+1列,直至第n列配置也是合理时,就找到了一个解。
接着改变第n列配置,希望获得下一个解。
另外,在任一列上,可能有n种配置。
开始时配置在第1行,以后改变时,顺次选择第2行、第3行、…、直到第n行。
当第n行配置也找不到一个合理的配置时,就要回溯,去改变前一列的配置。
得到求解皇后问题的算法如下:{ 输入棋盘大小值n;m=0;good=1;do {if (good)if (m==n){ 输出解;改变之,形成下一个候选解;}else 扩展当前候选接至下一列;else 改变之,形成下一个候选解;good=检查当前候选解的合理性;} while (m!=0);}在编写程序之前,先确定边式棋盘的数据结构。
比较直观的方法是采用一个二维数组,但仔细观察就会发现,这种表示方法给调整候选解及检查其合理性带来困难。
更好的方法乃是尽可能直接表示那些常用的信息。
对于本题来说,“常用信息”并不是皇后的具体位置,而是“一个皇后是否已经在某行和某条斜线合理地安置好了”。
n皇后与问题课程设计
n皇后与问题课程设计一、课程目标知识目标:1. 学生能理解“n皇后问题”的定义,掌握其基本的数学模型和求解方法。
2. 学生能运用逻辑推理和问题分解的策略,解决n皇后问题。
3. 学生理解递归算法的原理,并能够将其应用于n皇后问题的求解过程中。
技能目标:1. 学生培养逻辑思维和问题解决能力,通过解决n皇后问题,提升复杂问题的分析能力。
2. 学生掌握递归算法的设计和实现技巧,提高编程实践能力。
3. 学生通过小组合作,增强团队协作能力和沟通技巧。
情感态度价值观目标:1. 学生培养对计算机科学和数学建模的兴趣和热情,增强对科学探究的积极态度。
2. 学生在学习过程中体会团队合作的重要性,树立合作共赢的价值观。
3. 学生通过解决挑战性问题,培养面对困难的勇气和坚持不懈的精神。
课程性质分析:本课程为高中信息技术或计算机科学相关课程,旨在通过解决n皇后问题,将数学、逻辑和编程知识综合运用,提高学生的实践操作能力和创新思维能力。
学生特点分析:高中年级学生对基本逻辑思维和计算机编程有一定了解,具备一定的数学基础,对算法和问题求解具有较强的兴趣和探索欲望。
教学要求:1. 教学内容紧密联系实际,注重培养学生的动手操作能力和实际问题解决能力。
2. 教学过程中强调学生的主体地位,引导学生主动探究,发挥其创造性思维。
3. 教学评价关注学生在知识、技能和情感态度价值观方面的全面发展。
二、教学内容1. 引入n皇后问题,介绍其背景和数学定义,解释问题在计算机科学和逻辑思维训练中的重要性。
- 相关章节:算法与问题求解的基本概念。
2. 讲解n皇后问题的数学模型,分析问题约束条件和求解策略。
- 相关章节:逻辑推理与问题分析。
3. 介绍递归算法的基础知识,通过示例讲解递归在n皇后问题中的应用。
- 相关章节:递归算法设计与实现。
4. 设计教学活动,指导学生通过小组合作,运用已学知识编写程序解决n皇后问题。
- 相关章节:编程实践与团队合作。
5. 深化理解,探讨n皇后问题的扩展和变体,如更大规模的n皇后问题、优化算法等。
N皇后问题实验报告
N皇后问题实验报告电子工程学院A.实验内容在n×n格的棋盘上放置彼此不受攻击的n个皇后,按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子,求解可以放置的方法种数。
B.问题分析n后问题等于于在n×n格的棋盘上放置n个皇后,任何2个皇后不放在同一行或同一列或同一斜线上。
即规定每一列放一个皇后,不会造成列上的冲突;当第i 行被某个皇后占领后,则同一行上的所有空格都不能再放皇后,要把以i为下标的标记置为被占领状态。
C.算法设计1. 解决冲突问题:这个问题包括了行,列,两条对角线;列:规定每一列放一个皇后,不会造成列上的冲突;行:当第i行被某个皇后占领后,则同一行上的所有空格都不能再放皇后,要把以i为下标的标记置为被占领状态;对角线:对角线有两个方向。
在这我把这两条对角线称为:主对角线和从对角线。
在同一对角线上的所有点(设下标为(i,j)),要么(i+j)是常数,要么(i-j)是常数。
因此,当第i个皇后占领了第j列后,要同时把以(i+j)、(i-j)为下标的标记置为被占领状态。
2. 算法设计因为n皇后问题,从n大于11开始求解过程耗时就很长,所以定义x数组的最大值MAXNUM=30;即最大可解决30皇后问题。
1) 判断当前位置是否可放置皇后皇后k在第k行第x[k]列时,x[i]==x[k] 时,两皇后在同一列上;abs(x[i]-x[k])==abs(i-k)时,两皇后在同一斜线上;两种情况两皇后都可相互攻击,返回false表示不符合条件。
bool Place(int k){int i;i=1;while(i<k){if(x[i]==x[k]||abs(x[i]-x[k])==abs(i-k))return false;i=i+1;}return true;2) 输出当前解void Print(int x[],int n) {num++;printf("第%d\t种解法:(",num);for(int i=1;i<=n;i++) {printf("%d,",x[i]);if(i%n==0)printf(");\n"); }3) 回溯法搜索解空间void NQueens(int n){int k=1;x[1]=0;while(k>0){x[k]+=1;while(x[k]<=n&&!Place(k)) x[k]+=1;if(x[k]<=n)1 / 6{if(k==n)Print(x,n);else{k=k+1;x[k]=0;}}//回溯至上一行;elsek--;}}3. 实验结果及分析n皇后问题解的情况皇后的个问题的解数N=1 X=(1) N=2 无解N=3 无解N=4 X1=(2,4,1,3); X2=(3,1,4,2) N=5 X1=(1,3,5,2,4); X2=(1,4,2,5,3); X3=(2,4,1,3,5);X4=(2,5,3,1,4);X5=(3,1,4,2,5); X6=(3,5,2,4,1); X7=(4,1,3,5,2);X8=(4,2,5,3,1);X9=(5,2,4,1,3); X10=(5,3,1,4,2) N=6X1=(2,4,6,1,3,5);X2=(3,6,2,5,1,4);X3=(4,1,5,2,6,3);X4=(5,3,1, 6,4,2)N=7 40个解 N=8 92个解4. 实验程序随着N 的增大,解的个数增多,以N=4为例#include <stdio.h>#include<math.h>#define N 4 /* 定义棋盘大小 */static int sum; /* 当前已找到解的个数 */static int x[N];int place(int k){int j;for (j = 0; j < k; j ++)if (x[j] == x[k] || abs(j - k) == abs(x[j] - x[k])) return 0;2 / 6return 1;}/* 打印棋局 */void chessboard(){int i,j;int site[N];printf("第%d种解法:\n", ++ sum);for (i = 0; i < N; i ++) {for (j = 0; j < N; j ++)if (j == x[i]) {printf("Q ");site[i]=j+1;}else printf("* ");printf("\n");}printf("A%d(",sum);for(i = 0; i < N; i ++){printf("%d,",site[i]);}printf(");");printf("\n");}/* 回溯搜索解空间 */void backtrack(){int k = 0;x[0] = -1;while (k >= 0) {x[k] += 1; /* 向右移一列 *//* 向右移至出最右列或可以放置皇后的列 */ while ((x[k] < N) && !(place(k))) x[k] += 1; if (x[k] < N) /* 向右移未移出棋盘 */if (k == N - 1) chessboard(); /* 已移至最后一行 */else x[++ k] = -1; /* 向下移一行 */else k --; /* 回溯到上一行 */}}int main(void){backtrack();printf("%d皇后有%d个解:\n",N,sum); return 0;}3 / 6实验结果截图:5. 流程图4 / 6D.心得体会通过算法老师布置的这次大作业,首先使我们更好地理解皇后问题和回溯法的原理;其次,在作业过程中遇到的困难,使我们3人学会了如何合作才能更高效的解决问题;最后,在这次作业中,锻炼了我们收集资料,学习新技能的能力,感谢老师~E.参考文献《算法设计技巧与分析》——电子工业出版社《C程序设计》——西安电子科技大学出版社《回溯法》——百度文库5 / 6。
N皇后问题—回溯算法经典例题
N皇后问题—回溯算法经典例题题⽬描述: N 皇后是回溯算法经典问题之⼀。
问题如下:请在⼀个 n×n 的正⽅形盘⾯上布置 n 名皇后,因为每⼀名皇后都可以⾃上下左右斜⽅向攻击,所以需保证每⼀⾏、每⼀列和每⼀条斜线上都只有⼀名皇后。
题⽬分析: 在 N 皇后问题中,回溯算法思路是每⼀次只布置⼀个皇后,如果盘⾯可⾏,就继续布置下⼀个皇后。
⼀旦盘⾯陷⼊死局,就返回⼀步,调整上⼀个皇后的位置。
重复以上步骤,如果解存在,我们⼀定能够找到它。
可以看到,我们在重复“前进—后退—前进—后退”这⼀过程。
问题是,我们不知道⼀共需要重复这个过程多少次,也不能提前知道 n 是多少,更不知道每⼀次后退时需要后退⼏⾏,因此我们不能利⽤ for 循环和 while 循环来实现这个算法。
因此我们需要利⽤递归来实现代码结构。
逻辑如下:当⽅法布置完当前⾏的皇后,就让⽅法调⽤⾃⼰去布置下⼀⾏的皇后。
当盘⾯变成绝境的时候,就从当前⽅法跳出来,返回到上⼀⾏,换掉上⼀⾏的皇后再继续。
我们定义 NQueens(n) ⽅法,它负责输出所有成⽴的 n×n 盘⾯。
其中 1 代表皇后,0 代表空格。
代码:def NQueens(n): #输出所有成⽴的n·n盘⾯cols = [0 for _ in range(n)] #每⼀⾏皇后的纵坐标res = [] #结果列表def checkBoard(rowIndex): #检查盘⾯是否成⽴,rowIndex是当前⾏数for i in range(rowIndex):if cols[i]==cols[rowIndex]: #检查竖线return Falseif abs(cols[i]-cols[rowIndex]) == rowIndex-i: #检查斜线return Falsereturn Truedef helper(rowIndex): #布置第rowIndex⾏到最后⼀⾏的皇后if rowIndex==n: #边界条件board = [[0 for _ in range(n)] for _ in range(n)]for i in range(n):board[i][cols[i]] = 1res.append(board) #把当前盘⾯加⼊结果列表return#返回for i in range(n): #依次尝试当前⾏的空格cols[rowIndex] = iif checkBoard(rowIndex): #检查当前盘⾯helper(rowIndex+1) #进⼊下⼀⾏helper(0) #从第1⾏开始return resprint(NQueens(4))代码分析: 在 NQueens() ⽅法中,我们会定义 helper(x) ⽅法帮助实现递归结构。
n后问题实验报告
一.实验目的1. 了解皇后相互攻击的条件:如果任意两个皇后在同一行,同一列或同一对角线,则她们相互攻击。
2. 运用迭代的方法实现n皇后问题,求解得到皇后不相互攻击的一个解二.实验内容基本思路:用n元组x[1:n]表示n后问题的解,其中x[i]表示第i个皇后放在棋盘的第i行的第x[i]列。
抽象约束条件得到能放置一个皇后的约束条件:(1)x[i]!=x[k]; (2)abs(x[i]-x[k])!=abs(i-k)。
应用回溯法,当可以放置皇后时就继续到下一行,不行的话就返回到第一行,重新检验要放的列数,如此反复,直到将所有解解出。
在回溯法中,递归函数Backtrack(1)实现对整个解空间的回溯搜索。
Backtrack(i)搜索解空间的第i层子树。
类Queen的数据成员记录解空间的节点信息,以减少传给Backtrack函数的参数。
sum记录当前已找到的可行方案数。
运用回溯法解题通常包含以下三个步骤:(1)针对所给问题,定义问题的解空间;(2)确定易于搜索的解空间结构;(3)以深度优先的方式搜索解空间,并且在搜索过程中用剪枝函数避免无效搜索。
源代码:#include<iostream>using namespace std;class Queen{friend int nQueen(int);private:bool Place(int k);void Backtract(int t);int n,*x;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])) return false;return true;}void Queen::Backtract(int t){if (t>n){sum++;cout<<"第"<<sum<<"种方法:";for(int i=1;i<=n;i++)cout<<x[i]<<" ";cout<<endl;}else{for(int i=1;i<=n;i++){x[t]=i;if(Place(t)) Backtract(t+1);}}}int nQueen(int n){Queen X;X.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.Backtract(1);delete []p;return X.sum;}void main(){int n,m;cout<<"请输入皇后个数:";cin>>n;m=nQueen(n);cout<<endl;cout<<"有"<<m<<"种可行方法"<<endl; }三.实验的结果及分析……………四.实验心得体会通过这次实验理解了回溯法的基本思想:确定了解空间的组织结构后,回溯法就从开始结点(根结点)出发,以深度优先的方式搜索整个解空间。
n皇后问题-分支限界法
一、问题11、问题描述一、N 皇后问题在N*N 的棋盘上放置彼此不受攻击的N 个皇后。
按照国际象棋的规则,皇后可以攻击与之处于同一行或同一列或同一斜线上的棋子。
N 皇后的问题等价于在N*N 大小的棋盘中放置N 个皇后,任何2 个皇后都不放在同一行或同一列或同一斜线上。
使用队列式分支限界法,求出N 个皇后的一种放置方案。
2、算法设计思想分支限界法解向量:因为皇后不能同行或同列,所以我们可以用这样一个解向量来表示问题的解X[x1,x2…xn] x=[1,2,3表示];1~n行皇后位于的列数解空间:因为皇后不能同行同列,因此解空间为排列树,使用广度优先搜索的方式搜索整棵树剪枝函数:判断新摆放的皇后是否在已经摆放的皇后的斜线上3、算法过程描述第一行第一列放置皇后,这个节点成为拓展节点,产生n-1 个活结点,加入队列,第一行第二列到第n 列分别产生n-1 个活结点,加入队列,从队列取出第一个活结点,即第二行第二列,不满足剪枝函数的要求,除去这个节点,队列中的节点依次取出,满足剪枝函数的节点成为拓展节点产生活结点并加入队列,当成功进行到叶子节点时,就能得到问题的一个解,队列为空时,就得到了所有解4、算法实现及运行结果#include<iostream>#include<ctime>using namespace std;bool isOK(int n, int pieces[]){// 剪枝函数// 判断当前状态是否合理,即皇后会不会互相攻击for (int i = 1; i <= n-1; i++){for (int j = i + 1; j <= n; j++){int left = -(j - i);// 向左的斜线int right = (j - i);// 向右的斜线if (pieces[j] == pieces[i] + left||pieces[j] == pieces[i] + right) {// 第i 行皇后和第j 行皇后会互相攻击return false;}}}// 所有皇后都不会互相攻击return true;}void swap(int &a, int &b){int t = a;a = b;b = t;}void nQueen(int n, int t, int pieces[]){if (t > n){for (int i = 1; i <= n; i++){for (int j = 1; j < pieces[i]; j++)cout << "- ";cout << pieces[i]<<" ";for (int j = pieces[i] + 1; j <= n; j++) cout << "- "; cout << endl;}cout << endl;}else{for (int i = t; i <= n; i++){swap(pieces[t], pieces[i]);if (isOK(t, pieces)){nQueen(n, t + 1, pieces);}swap(pieces[t], pieces[i]);}}}int main (){int n;cin >> n;int *pieces = new int[n + 1];for (int i = 1; i <= n; i++){pieces[i] = i;}nQueen(n, 1, pieces);cout << "OK" << endl;system("pause");}5、算法复杂度分析及算法改进子集树0(nF)*剪枝函数(包括判断行列和斜线)0(n)=0(nF+1)。
n皇后问题_回溯法_递归实现__解释说明
n皇后问题回溯法递归实现解释说明1. 引言1.1 概述本文主要讨论的是n皇后问题及其解决方法。
n皇后问题是一个经典的数学问题,旨在找到如何将n个皇后放置在一个nxn的棋盘上,使得所有皇后彼此之间不会互相攻击。
这个问题具有一定难度,但可以通过回溯法和递归实现来有效解决。
1.2 文章结构本文共分为五个部分:引言、n皇后问题、回溯法解决n皇后问题的步骤、递归实现n皇后问题解决方案的详细步骤与算法思路以及结论。
引言部分主要对文章内容进行概述和介绍,并给出本文的结构安排。
1.3 目的本文旨在通过对n皇后问题的深入研究和探讨,介绍回溯法和递归实现在解决该问题中的应用方法。
通过详细说明算法步骤和思路,帮助读者理解如何使用回溯法和递归实现有效地解决n皇后问题,并对两种方法进行评价与讨论。
同时,还展望了可能的未来研究方向,为读者提供更多思考和拓展的空间。
本文旨在为对n皇后问题感兴趣的读者提供有益的参考和指导。
(文章引言部分完)2. n皇后问题:2.1 问题描述:n皇后问题是一个经典的组合问题,其中n表示棋盘上的行数和列数。
在一个nxn的棋盘上,要放置n个皇后,并且要求任意两个皇后之间不得互相攻击(即不能处于同一行、同一列或同一对角线上)。
这是一个相当困难的问题,因为随着n的增大,可能的解法呈指数增长。
2.2 解决方法介绍:为了解决n皇后问题,可以使用回溯法和递归实现的组合算法。
回溯法是一种通过尝试所有可能情况来找到解决方案的方法。
它通过逐步构建解,并在遇到无效解时进行回溯。
而递归是把大规模的问题分解成相似但规模更小的子问题来求解。
2.3 回溯法和递归实现的关系:在解决n皇后问题中,回溯法是主要思想,而递归则用于辅助实现回溯过程。
在每一步尝试放置一个皇后时,会先判断该位置是否与之前已经放置好的皇后冲突。
如果没有冲突,则继续考虑下一个位置,并以递归的方式调用自身。
如果找到一个有效解时,会结束递归并返回结果。
如果所有位置都无法放置皇后,则回溯至上一步进行下一种尝试。
N皇后问题
N皇后问题在国际象棋中,皇后的势力范围包括上、下、左、右、左上、左下、右上、右下八个方向。
N皇后问题就是求在一个N*N的棋盘中放置N个皇后的解法。
首先,讨论4x4棋盘中如何放置4个皇后,从中探讨出解决N皇后问题的规则假设有4x4棋盘如下:12(1,1)-----放置失败(左上角已有1个皇后)(34、第三行无法放任何皇后,所以回到(0,0)继续讨论56(2,1)-----放置78、第四行无法放置任何皇后,所以回到(1,3)继续讨论910、第三行无法放置任何皇后,所以回到起点继续讨论1112、(1,0)(1,1)(1,2)----放置失败(1,3)------放置成功1314、(3,0)(3,1)------失败(3,2)-----放置成功根据以上实例,总结解决该问题的构思:首先判断传入坐标位置是否可以放置皇后(八个方向是否有其他皇后,有返回false,无返回true)。
假设传入坐标为(X,Y),棋盘大小为NxN坐标上方:(X,Y-1)到(X,0)是否有其他皇后坐标下方:(X,Y+1)到(X,N-1)是否有其他皇后坐标左方:(X-1,Y)到(0,Y)是否有其他皇后坐标右方:(X+1,Y)到(N-1,Y)是否有其他皇后坐标左上方:(X-1,Y-1)到(X,0)或(0,Y)是否有其他皇后坐标右上方:(X+1,Y-1)到(X,0)或(N-1,Y)是否有其他皇后坐标左下方:(X-1,Y+1)到(X,N-1)或(0,Y)是否有其他皇后坐标右下方:(X+1,Y+1)到(X,N+1)或(N-1,Y)是否有其他皇后递归结束的条件:N个皇后都放置成功递归执行部分:判断传入坐标是否可放置皇后,可以则依次递归放置下一个详细程序代码:package Queue;publicclass queue {publicstaticchar ChessBoard[][] = newchar[8][8];publicstaticvoid main(String[] args) {int i,j;for(i = 0;i<8;i++){for(j =0;j<8;j++){ChessBoard[i][j] = 'X';}}N_Queues(0,0,0);System.out.println("The graph of Queues on the ChessBoard");System.out.println(" 0 1 2 3 4 5 6 7 ");System.out.println(" +---+---+---+---+---+---+---+---+");for(i = 0 ;i<8;i++){System.out.print(" "+i+" ");for(j = 0;j<8;j++){System.out.print("-"+ChessBoard[i][j]+"-|");}System.out.println("");System.out.println(" +---+---+---+---+---+---+---+---+");}}//递归解决N皇后问题publicstaticint N_Queues(int LocX,int LocY,int Queues){int i,j;int Result = 0;if(Queues == 8){return 1;}elseif(QueuePlace(LocX,LocY)){ChessBoard[LocX][LocY] = 'Q';for(i = 0;i<8;i++){for(j = 0;j<8;j++){Result += N_Queues(i, j, Queues+1);if(Result>0){break;}}}if(Result>0){return 1;}else{ChessBoard[LocX][LocY] = 'X';return 0;}}elsereturn 0;}privatestaticboolean QueuePlace(int LocX, int LocY) {int i,j;if(ChessBoard[LocX][LocY]!='X'){returnfalse;}for(j = LocY-1;j>=0;j--){if(ChessBoard[LocX][j] != 'X'){returnfalse;}}for(j = LocY+1;j<8;j++){if(ChessBoard[LocX][j]!='X'){returnfalse;}}for(i = LocX-1;i>=0;i--){if(ChessBoard[i][LocY]!='X'){returnfalse;}}for(i = LocX+1;i<8;i++){if(ChessBoard[i][LocY]!='X'){returnfalse;}}i = LocX-1;j = LocY-1;while(i>=0 && j>=0){if(ChessBoard[i--][j--] !='X'){ returnfalse;}}i = LocX+1;j = LocY-1;while(i<8 && j>=0){if(ChessBoard[i++][j--] !='X'){ returnfalse;}}i = LocX-1;j = LocY+1;while(i>=0&& j<8 ){if(ChessBoard[i--][j++] !='X'){ returnfalse;}}i = LocX+1;j = LocY+1;while(i<8 && j<8){if(ChessBoard[i++][j++] !='X'){ returnfalse;}}returntrue;}}显示结果为:The graph of Queues on the ChessBoard 0 1 2 3 4 5 6 7+---+---+---+---+---+---+---+---+0 -Q-|-X-|-X-|-X-|-X-|-X-|-X-|-X-|+---+---+---+---+---+---+---+---+1 -X-|-X-|-X-|-X-|-Q-|-X-|-X-|-X-|+---+---+---+---+---+---+---+---+2 -X-|-X-|-X-|-X-|-X-|-X-|-X-|-Q-|+---+---+---+---+---+---+---+---+3 -X-|-X-|-X-|-X-|-X-|-Q-|-X-|-X-|+---+---+---+---+---+---+---+---+4 -X-|-X-|-Q-|-X-|-X-|-X-|-X-|-X-|+---+---+---+---+---+---+---+---+5 -X-|-X-|-X-|-X-|-X-|-X-|-Q-|-X-|+---+---+---+---+---+---+---+---+6 -X-|-Q-|-X-|-X-|-X-|-X-|-X-|-X-|+---+---+---+---+---+---+---+---+7 -X-|-X-|-X-|-Q-|-X-|-X-|-X-|-X-|+---+---+---+---+---+---+---+---+对于N皇后,递归一条龙同理可得!白宇的博客详细介绍了有关八皇后的几种不同算法,有空就去看看。