八皇后问题
来源:互联网 发布:买一个域名要多少钱 编辑:程序博客网 时间:2024/05/01 15:56
回溯法:八皇后问题,一个经典问题
在程序设计中还有一种方法叫做"回溯法".他不是按照某种公式或确定的法则,求问题的解,而是通过试探和纠正错误的策略,找到问题的街.这种方法一般是从一个原始状态出发,通过若干步试探,最后达到目标状态终止.
回溯法在理论上来说,就是在一棵搜索树中从根结点出发,找到一条达到满足某条件的子结点的路径.在搜索过程中,对于每一个中间结点,他的位置以及向下搜索过程是相似的,因此完全可以用递归来处理.典型的例子就是著名的"八皇后问题".
"八皇后问题"是在国际象棋棋盘上放置八个皇后,使她们不能相吃.国际象棋中的皇后可以吃掉与她处于同一行,同一列,同一对角线上的棋子.因此每一行只能摆放一个皇后.因共有八行,所以每行有且只有一个皇后.
在本例中皇后的位置有一个一维数组来存放A(I)=J表示第I行皇后放在第J列.下面主要来看看怎么样判断皇后是否安全的问题.(1)首先,用一维数组来表示,已经解决了不在同一行的问题.(2)对于列可以引进一个标志数组C[J],若J列上已放了皇后,则C[J]=FALSE.(3)对于左上右下的对角线I-J为一常量,位于[-7,+7]之间,再此引入标志数组L[-7..7];对于左下右上的对角线,类似的有I+J等于常量,用数组R[2..16]来表示.当在第I行,第J列上放置了皇后,则只需设置:C[J]:=FALSE; L[I-J]:=FLASE; R[I+J]:=FALSE就可以解决皇后的安全问题了.
在程序设计中还有一种方法叫做"回溯法".他不是按照某种公式或确定的法则,求问题的解,而是通过试探和纠正错误的策略,找到问题的街.这种方法一般是从一个原始状态出发,通过若干步试探,最后达到目标状态终止.
回溯法在理论上来说,就是在一棵搜索树中从根结点出发,找到一条达到满足某条件的子结点的路径.在搜索过程中,对于每一个中间结点,他的位置以及向下搜索过程是相似的,因此完全可以用递归来处理.典型的例子就是著名的"八皇后问题".
"八皇后问题"是在国际象棋棋盘上放置八个皇后,使她们不能相吃.国际象棋中的皇后可以吃掉与她处于同一行,同一列,同一对角线上的棋子.因此每一行只能摆放一个皇后.因共有八行,所以每行有且只有一个皇后.
在本例中皇后的位置有一个一维数组来存放A(I)=J表示第I行皇后放在第J列.下面主要来看看怎么样判断皇后是否安全的问题.(1)首先,用一维数组来表示,已经解决了不在同一行的问题.(2)对于列可以引进一个标志数组C[J],若J列上已放了皇后,则C[J]=FALSE.(3)对于左上右下的对角线I-J为一常量,位于[-7,+7]之间,再此引入标志数组L[-7..7];对于左下右上的对角线,类似的有I+J等于常量,用数组R[2..16]来表示.当在第I行,第J列上放置了皇后,则只需设置:C[J]:=FALSE; L[I-J]:=FLASE; R[I+J]:=FALSE就可以解决皇后的安全问题了.
问题描述:在标准国际象棋的棋盘上(8*8格)准备放置8只皇后,我们知道,国际象棋中皇后的威力是最大的,她既可以横走竖走,还可以斜着走,遇到挡在她前进路线上的敌人,她就可以吃掉对手。要求在棋盘上安放8只皇后,使她们彼此互相都不能吃到对方,求皇后的放法
/************************************************************************/ /* */ /* 问题:在8×8的国际象棋棋盘上放置8个皇后,要求任意两个皇后 */ /* 不能在同一行、同一列或同一条对角线上。 */ /* */ /* 本程序使用递归-回溯法求解8皇后问题。Visual C++ 6.0 调试通过。 */ /* 作者 晨星 2002年5月9日 */ /* */ /************************************************************************/ #include <stdio.h> #include <conio.h> #include <math.h> #define QUEENS 8 //!记录解的序号的全局变量。 int iCount = 0; //!记录皇后在各列上的放置位置的全局数组。 int Site[QUEENS]; //!递归求解的函数。 void Queen(int n); //!输出一个解。 void Output(); //!判断第n个皇后放上去之后,是否有冲突。 int IsValid(int n); /*----------------------------Main:主函数。 ----------------------------*/ void main() { //!从第0列开始递归试探。 Queen(0); //!按任意键返回。 getch(); } /*-----------------Queen:递归放置第n个皇后,程序的核心!----------------*/ void Queen(int n) { int i; //!参数n从0开始,等于8时便试出了一个解,将它输出并回溯。 if(n == QUEENS) { Output(); return; } //!n还没到8,在第n列的各个行上依次试探。 for(i = 1 ; i <= QUEENS ; i++) { //!在该列的第i行上放置皇后。 Site[n] = i; //!如果放置没有冲突,就开始下一列的试探。 if(IsValid(n)) Queen(n + 1); } } /*------IsValid:判断第n个皇后放上去之后,是否合法,即是否无冲突。------*/ int IsValid(int n) { int i; //!将第n个皇后的位置依次于前面n-1个皇后的位置比较。 for(i = 0 ; i < n ; i++) { //!两个皇后在同一行上,返回0。 if(Site[i] == Site[n]) return 0; //!两个皇后在同一对角线上,返回0。 if(abs(Site[i] - Site[n]) == (n - i)) return 0; } //!没有冲突,返回1。 return 1; } /*------------Output:输出一个解,即一种没有冲突的放置方案。------------*/ void Output() { int i; //!输出序号。 printf("No.%-5d" , ++iCount); //!依次输出各个列上的皇后的位置,即所在的行数。 for(i = 0 ; i < QUEENS ; i++) printf("%d " , Site[i]); printf("n"); } STL源代码 用了STL, 方法是一样的. #include <iostream> #include <string> using namespace std; void queen(const string t, const string s) { if (s=="") cout<<t<<endl; else for (int i=0; i<s.length(); i++) { bool safe=true; for (int j=0;j<t.length();j++) { if (t.length()-j==abs(s[i]-t[j])) safe=false; } if (safe) queen(t+s[i], s.substr(0,i)+s.substr(i+1)); } } int main() { string s="01234567"; queen("",s); system("PAUSE"); exit(EXIT_SUCCESS); } 递归解八皇后问题 /*递归法解八皇后问题*/ /*作者黄国瑜,《数据结构(C语言版)》清华大学出版社*/ char Chessboard[8][8]; /*声明8*8的空白棋盘*/ int N_Queens(int LocX, int LocY, int Queens) /*递归*/ { int i,j; int Result=0; if(Queens == 8)/*递归结束条件*/ return 1; else if(QueenPlace(LocX,LocY))/*递归执行部分*/ { Chessboard[LocX][LocY] = 'Q'; for(i=0;i<8;i++) for(j=0;j<8;j++) { Result += N_Queens(i,j,Queens+1); if(Result>0) break; } if(Result>0) return 1; else { Chessboard[LocX][LocY] = 'X'; } } else return 0; } int QueenPlace(int LocX,int LocY) /*判断传入坐标本身及入八个方向上是否有皇后*/ { int i,j; if(Chessboard[LocX][LocY] != 'X') return 0; for(j=LocY-1;j>=0;j--) if(Chessboard[LocX][j] != 'X') return 0; for(j=LocY+1;j<8;j++) if(Chessboard[LocX][j] != 'X') return 0; for(i=LocX-1;i>=0;i--) if(Chessboard[i][LocY] != 'X') return 0; for(i=LocX+1;i<8;i++) if(Chessboard[i][LocY] != 'X') return 0; i= LocX - 1; j= LocY - 1; while (i>=0&&j>=0) if(Chessboard[i--][j--] != 'X') return 0; i= LocX + 1; j= LocY - 1; while (i<8&&j>=0) if(Chessboard[i++][j--] != 'X') return 0; i= LocX - 1; j= LocY + 1; while (i>=0&&j<8) if(Chessboard[i--][j++] != 'X') return 0; i= LocX + 1; j= LocY + 1; while (i<8&&j<8) if(Chessboard[i++][j--] != 'X') return 0; return 1; } main() /*主程序*/ { int i,j; for(i=0;i<8;i++) for(j=0;j<8;j++) Chessboard[i][j] = 'X'; N_Queens(0,0,0); printf("the graph of 8 Queens on the Chessboard.is:n"); for(i=0;i<8;i++) for(j=0;j<8;j++) { if(Chessboard[i][j] == 'Q') printf("(%d,%d)n",i,j); } getch(); } /********************************************************* *****************八皇后问题******************************* ************根据严书给的类c算法求得************************ *********************************************************/ #include<stdio.h> #define N 8 int col=1,row=1,slash=1,bslash=1; int a[N][N]; int p,q,k,l; int num=0; void trial(int i) { int j; /*注 意,这里的j 一定要设为内部变量*/ if(i==N) { num++; for(k=0;k<N;k++) { for(l=0;l<N;l++) { if(a[k][l]==1) printf("@"); else printf("*"); } printf("n"); } printf("nn"); getchar(); } else { for(j=0;j<N;j++) { for(k=0;k<i;k++) if(a[k][j]==1) { col=0; break; } /*列*/ p=i-1; q=j+1; while((p>=0)&&(q<N)) { if(a[p][q]==1) { slash=0; break; } p--; q++; } p=i-1; q=j-1; /*对角*/ while((p>=0)&&(q>=0)) { if(a[p][q]==1) { bslash=0; break; } p--; q--; } /*斜对角*/ if((col==1)&&(slash==1)&&(bslash==1)) /*条件判断*/ { a[i][j]=1; trial(i+1); } col=1;slash=1;bslash=1; a[i][j]=0; } } } void main() { trial(0); printf("%dn",num); getchar(); }
- 八皇后 n皇后 问题
- 八皇后N皇后问题
- 八皇后问题
- 八皇后问题
- 八皇后问题
- 八皇后问题(2)
- 八皇后问题(3)
- 八皇后问题
- 八皇后问题程序
- 浅谈八皇后问题
- 八皇后问题
- 八皇后问题
- 八皇后问题
- 八皇后问题
- 八皇后问题求解
- 八皇后问题
- 八皇后问题
- 八皇后问题
- 博客备份工具
- You didn't specify an interface on which to capture packets.
- hdu2106
- 三条狗闯进养兔场吓死600余只兔子(图)
- hdu 2035
- 八皇后问题
- 实用算法实践-第 4 篇散列表
- Linux 中的 VFS 文件系统机制
- hdu2091
- flash绘图API :蚂蚁线
- 16. 26. 4. 刷新图片-古老的办法 Flush an image
- hdu 2027
- hdu Financial Management
- hdu 2005