您的位置:首页 > 其它

从N-皇后问题看回溯法

2010-12-10 19:17 253 查看
使用递归:

1 #include <stdio.h>

2 #include <stdlib.h>

3 #include <string.h>

4 #include <stddef.h>

5

6 int c = 0;

7

8 int print_queens(int *queens, int n)

9 {

10 int i, j;

11

12 for (i = 0; i < n; i++)

13 {

14 for (j = 0; j < queens[i]; j++)

15 {

16 printf("-");

17 }

18 printf("*");

19

20 for(j++; j < n; j++)

21 {

22 printf("-");

23 }

24 printf("/n");

25 }

26 return 0;

27 }

28

29 int check_position(int *queens, int row)

30 {

31 int i;

32

33 for (i = 0; i < row; i++)

34 {

35 if (queens[i] == queens[row] ||

36 abs(queens[row] - queens[i]) == abs(row - i))

37 {

38 return -1;

39 }

40 }

41 return 0;

42 }

43

44 int queens_solution(int *queens, int row, int n)

45 {

46 int col;

47

48 if (row >= n)

49 {

50 print_queens(queens, n);

51 //printf("%d./n", ++c);

52 }

53 else

54 {

55 for (col = 0; col < n; col++)

56 {

57 queens[row] = col;

58 if (check_position(queens, row) == 0) //check success

59 {

60 queens_solution(queens, row+1, n); //try next row

61 }

62 }

63 }

64

65 return 0;

66 }

67

68 int main()

69 {

70 int queens[] = {-1, -1, -1, -1, -1, -1, -1, -1};

71 queens_solution(queens, 0, 8);

72 printf("There is %d answers for the %d queen question", c, sizeof(queens) / sizeof(int));

73 getchar();

74 return 0;

75 }

76

如果不使用递归,则需要自己模拟出一个压栈和出栈的过程:

只需要做出如下修改即可:

1 #include <stdio.h>

2

3 #define N 4 /* 定义棋盘大小 */

4

5 static int sum; /* 当前已找到解的个数 */

6

7 static int x
; /* 记录皇后的位置,x[i]=j表示皇后放在棋盘的第i行的第j列 */

8

9

10 /* 确定某一位置皇后放置与否,放置则返回1,反之返回0 */

11 int place(int k)

12 {

13 int j;

14 /* 测试皇后k在第k行第x[k]列时是否与前面已放置好的皇后相攻击. x[j] == */

15 /* x[k] 时,两皇后在同一列上;abs(k - j) == abs(x[j] - x[k]) 时,两皇 */

16 /* 后在同一斜线上。两种情况两皇后都可相互攻击,故返回0表示不符合条件。*/

17 for (j = 0; j < k; j ++)

18 if (x[j] == x[k] || abs(j - k) == abs(x[j] - x[k])) return 0;

19

20 return 1;

21 }

22

23 /* 打印棋局 */

24 void chessboard()

25 {

26 int i,j;

27 printf("第%d种解法:/n", ++ sum);

28 for (i = 0; i < N; i ++) {

29 for (j = 0; j < N; j ++)

30 if (j == x[i]) printf("Q ");

31 else printf("* ");

32 printf("/n");

33 }

34 printf("/n");

35 }

36

37 /* 回溯搜索解空间 */

38 void backtrack()

39 {

40 int k = 0;

41

42 x[0] = -1;

43 while (k >= 0) {

44 x[k] += 1; /* 向右移一列 */

45 /* 向右移至出最右列或可以放置皇后的列 */

46 while ((x[k] < N) && !(place(k))) x[k] += 1;

47 if (x[k] < N) /* 向右移未移出棋盘 */

48 if (k == N - 1) chessboard(); /* 已移至最后一行 */

49 else x[++ k] = -1; /* 向下移一行 */

50 else k --; /* 回溯到上一行 */

51 }

52 }

53

54

55

56 int main(void)

57 {

58 backtrack();

59 getch();

60 return 0;

61 }

62
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: