回溯法 (又称试探法)
具体方法会在下面继续讲解
八皇后定义
一个八行八列的棋盘 同一个横排 竖排斜线不能有两个或两个以上皇后
根据这个规则 下图 第五行没有一个位置满足条件
于是回到第四行 继续在下一列试探
解决这个问题并不需要定义一个8*8的二维数组 而是学会 存储
我们定义三个数组 分别是 cal ,left, right,
cal 存储当前列是否有皇后 如果有 修改值为1
left存储 左下方向斜线 是否有值
right存储右下斜线是否有值
每个left下标可用i-j+7来表示
每个right下标可用i+j表示
#include <stdio.h>
int col[100]={ 0 };
int left[100]={ 0 };
int right[100]={ 0 };
void Queen(int i);
void Print();
int sum = 0;
void Queen(int i)
{
//每次放慢了就调用输出 我定义了一个sum 记录有几个解
if(i == 8) {
Print();
sum++;
return;
}
int j;
for(j=0;j<8;j++)
{
if((!col[j])&&(!left[i+j])&&(!right[i-j+7]))//j列能放
{
col[j]=i + 1;//这样就可以记录每列皇后放在哪一行 输出就输出这个!
left[i+j]=1;
right[i-j+7]=1;
//i++ 这里不能i++ 因为如果这样 return到上一级的时候还要给i--
//这样体现 一层一层调用
if(i<8) Queen(i + 1);
//每次调用成功/放皇后失败之后都要 杀掉这个循环的当前皇后
col[j] = 0;
left[i + j] = 0;
right[i - j + 7] = 0;
}
}
return;//返回到主函数
}
void Print()
{
printf("\n");
for(int k=0;k<8;k++)
{
printf("%d\t",col[k]);
}
}
int main()
{
Queen(0);
printf("sum = %d\n", sum);
}