八皇后

问题陈述:

  国际象棋中的皇后可以直线前进,吃掉遇到的所有棋子,如果棋盘上有八个皇后,则这八个皇后如何相安无事的放置在棋盘上?

 

问题解法:

  关于棋盘的问题,都可以用递归求解,然而如何减少递归的次数?在八皇后问题中,不必要检查所有的格子,例如若某列检查过,该列的其它格子就不用检查了,这种方法称为分支修剪。

 

代码详解:

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstdlib>
 4 #define N 8
 5 
 6 using namespace std;
 7 
 8 int column[N+1];    //同行是否有皇后,1表示有
 9 int rup[2*N+1];     //右上及左下是否有皇后 x+y = c
10 int lup[2*N+1];     //左上及右下是否有皇后 x-y = c
11 int queen[N+1] = {0};   //皇后纵坐标
12 int num;        //解法编号
13 
14 void backtrack(int);    //递归求解
15 void showAnswer();
16 
17 int main()
18 {
19     int i;
20     num = 0;
21 
22     for(i=0; i<=N; i++) {
23         column[i] = 1;
24     }
25 
26     for(i=1; i<=2*N; i++) {
27         rup[i] = lup[i] = 1;
28     }
29 
30     //从第一列开始遍历
31     backtrack(1);
32 
33     return 0;
34 }
35 
36 void backtrack(int i) {
37     int j;
38     if(i>N) {
39         showAnswer();
40     }else {
41         for(j=1; j<=N; j++) {
42             //判断横向 对角线方向是有皇后 
43             if(column[j]==1 && rup[i+j]==1 && lup[i-j+N]==1) {
44                 queen[i] = j;
45                 column[j] = rup[i+j] = lup[i-j+N] = 0;
46                 //遍历下一列 
47                 backtrack(i+1);
48                 column[j] = rup[i+j] = lup[i-j+N] = 1;
49             }
50         }
51     }
52 }
53 
54 void showAnswer() {
55     int x, y;
56     printf("\nSolve %d\n", ++num);
57     for(y=1; y<=N; y++) {
58         for(x=1; x<=N; x++) {
59             if(queen[y] == x) {
60                 printf("Q ");
61             }else {
62                 printf("* ");
63             }
64         }
65         printf("\n");
66     }
67 }

 

效果图(92种摆法):

 

转载请注明出处:http://www.cnblogs.com/michaelwong/p/4290858.html

posted @ 2015-02-13 20:12  HelloMichaelWong  阅读(921)  评论(0编辑  收藏  举报