八皇后

问题陈述:

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

八皇后

 

问题解法:

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

 

代码详解:

 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

你可能感兴趣的:(八皇后)