递归回溯法解决八皇后问题
八皇后问题是一个以国际象棋为背景的问题:如何能够在 8×8 的国际象棋棋盘上放置八个皇后,使得任何一个皇后都无法直接吃掉其他的皇后?为了达到此目的,任两个皇后都不能处于同一条横行、纵列或斜线上。如图:

1)从第一行开始,为皇后找到安全位置|y1-y2| != |x1-x2| ,然后跳到下一行(这个表达式是利用斜率的公式防止两个皇后在同一条斜线上)
2)如果在第n行出现死胡同,如果该行为第一行,棋局失败,否则后退到上一行,在进行回溯
3)如果在第8行上找到了安全位置,则棋局成功。
程序如下:
在程序中用queen数组代表皇后的位置,例如:queen[2]=3代表皇后在第二行第三列的位置。
queen[i] == x || y - i == abs(x - queen[i])这个判断条件是由规则得出,两个皇后既不能在同一列也不能在同一斜线,y - i == abs(x - queen[i])这个判断是由斜率的公式得来。
#include <stdio.h>
#define QUEEN_NUM 8
int queen[QUEEN_NUM];
// 在第y行上放置皇后
void place(int y);
// 检测在第y行第x列能否放置皇后
int check(int y, int x);
void show();
int main(void)
{
place(0);
return 0;
}
int check(int y, int x)
{
int i;
for (i=0; i<y; i++)
{
if (queen[i] == x || y - i == abs(x - queen[i]))
return 0;
}
return 1;
}
void show()
{
int i;
int j;
static int count = 0;
printf("第%d个解
", ++count);
for (i=0; i<QUEEN_NUM; i++)
{
printf("(%d, %d) ", i, queen[i]);
}
putchar('
');
for (i=0; i<QUEEN_NUM; i++) // 行
{
for (j=0; j<QUEEN_NUM; j++) // 列
{
if (queen[i] == j)
printf("Q ");
else
printf("x ");
}
putchar('
');
}
}
void place(int y)
{
if (y == 8)
{
show();
return;
}
int i;
for (i=0; i<QUEEN_NUM; i++) // 在第y行的每一列上试探
{
if (check(y, i))
{
queen[y] = i;
place(y+1); // 在下一行放置皇后
}
}
}