八皇后问题
假设将八个皇后放在国际象棋盘上(8*8正方形),两两之间无法攻击(任意两个不可在同一行,同一列或同一斜线上)
算法:
1.在 n * n 的一个棋盘上,最多只能放置 n 个皇后
2.放置第一个皇后在左上角,之后在下一排后一列放置第二个皇后,不行向后一列挪直到合适,然后再向下一排后一列放置下一个皇后
3.当某一排皇后每一列都不合适时,就回到上一排,后移一列,一直到 n 个皇后放置完。
#include<stdio.h>
#include<math.h>
#include<stdlib.h>
#define N 8 /* 定义棋盘大小 */
static int sum; /* 当前已找到解的个数 */
static int x[N]; /* 记录皇后的位置,x[i]表示皇后i放在棋盘的第i行的第x[i]列 */
//判断每行皇后不攻击的正确位置
int DeterRightPlace(int line)
{
/* 测试皇后k在第k行第x[k]列时是否与前面已放置好的皇后相攻击。 x[j] == x[k] 时,两皇后在同一列上;abs(k - j) == abs(x[j] - x[k]) 时,两皇后在同一斜线上。两种情况两皇后都可相互攻击,故返回0表示不符合条件。*/
for (int j = 0; j < line; j ++) //j为每行列下标
if (abs(line - j) == abs(x[j] - x[line]) || (x[j] == x[line])) //Abs函数 :返回数字的绝对值。 数字的绝对值是其无符号的数值大小。例如,Abs(-1) 和 Abs(1) 都返回 1 。头文件:<math.h>
{
return 0;
}
return 1;
}
//显示(打印)
void Show()
{
printf("第%d种解法:\n", ++ sum);
for (int i = 0; i < N; i ++)//皇后0——N-1
{
for (int j = 0; j < N; j ++) //行和列的下标
{
if (j == x[i])
{
printf("%d ",i+1);
}
else
{
printf("* ");
}
}
printf("\n");
}
printf("\n");
}
//一行一行放皇后
void PutQueen(int line) //line为已经安置皇后的行数
{
/* line == N 时,得到一个新的N皇后互不攻击的放置方案 */
if (line == N)
{
Show() ;//打印
}
else
{
for (int i = 0; i < N; i ++)//行下标
{
x[line] = i;
if (DeterRightPlace(line))
{
PutQueen(line+1); //递归,下一行
}
}
}
}
int main(void)
{
PutQueen(0);
system("pause");
return 0;
}