八皇后问题:皇后可以在横、竖、斜线上不限步数地吃掉其他棋子。如何将8个皇后放在棋盘上(有8 * 8个方格),使它们谁也不能被吃掉!
八皇后问题有92种解
算法思路:
1、初始化i=1;
2、初始化j=1;
3、从第i行开始,恢复(i,j)位置的可走性(这样保证所有的结果都能求出):
a、位置j可放皇后标记位置(i, j),i++,转步骤2;
b、位置j不可放,j++,转步骤a;
c、当j>8时,回溯到上一步,i--,转步骤3。
4、结束,显示结果
代码实现:
#include <stdio.h> #define N 8 typedef struct Pos { int ipos; int jpos; }Pos; static char board[N+2][N+2]; //加2的原因是为了画边界 static Pos pos[] = { {-1,-1}, {-1,0}, {-1,1} }; static int count = 0; //用于统计解决方法的个数 void init() { int i=0; int j=0; for( j = 0; j < N+2; j++ ) { board[0][j] = '#'; board[j][0] = '#'; board[N+1][j] = '#'; board[j][N+1] = '#'; } for(i = 0; i < N; i++) for(j = 0; j<N; j++) board[i+1][j+1] = ' '; } void display() { int i = 0; int j = 0; for(i = 0; i <N+2; i++) { for(j = 0; j<N+2; j++) printf("%c", board[i][j]); printf("\n"); } } int Check(int i, int j) { int = 1; int p = 0; for( p = 0; p < 3; p++ ) { int ni = i; int nj = j; while( ret && ( board[ni][nj] != '#' ) ) //不能写成0<ni && 0<nj 这样会使解的数目减少 { ni += pos[p].ipos; nj += pos[p].jpos; if( board[ni][nj] == '*' ) ret = 0; } } return ret; } void find(int i) //这样做是为了能够递归回溯,得到所有的求解方法 { int j = 0; //边界条件 if(i>N) { count++; printf("Solution%d\n", count); display(); } else for( j = 1; j <= N; j++ ) if( Check(i, j) ) { board[i][j] = '*'; find(i+1); board[i][j] = ' '; //这样做使得程序能够回溯求解正确解 } } int main() { init(); find(1); return 0; }