C语言解决八皇后问题
1 #include <stdio.h> 2 #include <stdlib.h> 3 4 /* this code is used to cope with the problem of the eight queens. 5 * array borad[9][9] is a virtual borad. 6 * line 0 and volumn 0 is ignored. 7 * at first we find a place to set a queen on it, then mark this queen's 8 * domain. the way of marking domain is add 1 on the board[line][volumn], 9 * so the number of board[line][volumn] means this place can attacked by 10 * how many queens. after we mark this queen's domain, we move on to next line. 11 * if there is no next line, we got a solution */ 12 /* 这些代码主要用来解决八皇后问题 13 * 数组borad[9][9]是一个虚拟的棋盘。 14 * 第0行跟第0列被忽略 15 * 在最开始时,我们在某一行上找到一个位置,放上皇后后,我们把这个皇后能 16 * 攻击的范围都标志起来。我们标志的方法是在board[行][列]上加1, 17 * 所以board[行][列]上的值意味着这个位置能被多少个皇后攻击 18 * 当我们标志好这个皇后的范围后,我们就跳到下一行去。 19 * 如果已经没有下一行了,那么我们就找到一个放置方法了 */ 20 21 /* if a place on board have been marked by NONE 22 * it means no queen can attack this place, it is a potential place to set a queen */ 23 /* 如果棋盘上一个位置被设置为NONE,意味着没有皇后能攻击这个位置,这个位置可以被设置为皇后 */ 24 #define NONE (0) 25 #define QUEEN (-1) 26 27 #define OCCUPY (1) 28 #define DISOCCUPY (0) 29 30 void Compute(int line) ; 31 void PrintBorad(void) ; 32 void operate_borad(int line, int volumn, int function) ; 33 34 int main(void) 35 { 36 Compute(1) ; 37 return 0 ; 38 } 39 40 /* ignored the first line and the first volumn */ 41 int borad[9][9] ; 42 43 /* this is a recursive function. 44 * it will find a queen on this line, 45 * then fine next one of next line by call itself */ 46 /* 这是一个递归函数。在某一行上找到皇后的位置,然后调用自己找下一行的皇后 */ 47 void Compute(int line) 48 { 49 int i ; 50 static int num_of_solution = 0; 51 52 for(i = 1; i <= 8; i++) 53 if(borad[line][i] == NONE) 54 { 55 operate_borad(line, i, OCCUPY) ; 56 if(line == 8) // find a solution 57 { 58 printf("%d\n", ++num_of_solution) ; 59 PrintBorad() ; 60 } 61 else Compute(line +1) ; /* contine to next line */ /* 查找一行的皇后 */ 62 operate_borad(line, i, DISOCCUPY) ; 63 } 64 } 65 66 /* function: 67 * if function is OCCUPY, then set a flag of queen on borad[line][volumn] 68 * and set a flag on the domain of this queen 69 * if function is DISOCCUPY, then clear flag of queen on borad[line][volumn] 70 * and clear the flag on the domain of this queen */ 71 /* 功能: 72 * 如果function变量是OCCUPY,那么在board[line][volumn]上放上皇后, 73 * 并设置这个皇后的攻击范围 74 * 如果function变量是DISOCCUPY,那么把皇后从board[line][volumn]上清除 75 * 并清除这个皇后在其攻击范围上所设置的标志 */ 76 void operate_borad(int line, int volumn, int function) 77 { 78 int i, j, *temp, nl, nv ; 79 80 borad[line][volumn] = (function == OCCUPY ? QUEEN : NONE) ; 81 82 /* i and j are used to decide the direction*/ 83 for(i = -1; i <= 1; i++) 84 for(j = -1; j <= 1; j++) 85 if(i == 0 && j == 0) continue ; 86 else 87 for(nl = line +i, nv = volumn +j ; 88 nl >= 1 && nl <= 8 && nv >= 1 && nv <= 8 ; 89 nl += i, nv += j) 90 { 91 temp = &borad[nl][nv] ; 92 /* add one means this place can be attack by another queen */ 93 function == OCCUPY ? (*temp)++ : (*temp)-- ; 94 } 95 } 96 /* function: print the board on the screen */ 97 /* 打印棋盘 */ 98 void PrintBorad(void) 99 { 100 int x, y, chess ; 101 102 for(x = 1; x <= 8; x++) 103 { 104 for(y = 1; y <= 8; y++) 105 { 106 chess = borad[x][y] ; 107 if(chess != QUEEN) 108 putchar('*') ; 109 else 110 putchar('Q') ; 111 } 112 putchar('\n') ; 113 } 114 }