#include<stdio.h>
int place[8]={0};//皇后位置,下标代表行,数值代表列
bool flag[8]={1,1,1,1,1,1,1,1};//定义列
bool d1[15]={1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};//定义上对角线
bool d2[15]={1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};//定义下对角线
/*定义上对角线(共有15个对角线(diagonal)
因此定义一个长度为15的bool型数组,
初值为1代表该对角线没有被皇后占领,
若被皇后占领则赋值为0*/
int number=0;//记录输出次数
void output()//定义输出函数
{
int col,i,j;
number++;//每调用一次输出函数number自加一次,记录摆放方法个数
printf("No.%d\n",number);
int table[8][8]={0};//设置一个8*8的棋盘,所有位置赋0表示没旗子
for (i=0;i<8;i++)
{
table[i][place[i]]=1;//把皇后下下来
//将这一种情况的每个皇后所在位置赋值为1,place数组,i代表行,place[i]代表列
}
for (i=0;i<8;i++)//依次遍历输出table二维数组即可
{
for (j=0;j<8;j++)
{
printf("%d",table[i][j]);
}
printf("\n");//每输出满1行,换行
}
}
int queen(int n )//定义递归回溯函数,每层递归算一行的每一列
{
int col;
for (col=0;col<8;col++)
{
if (flag[col]&&d1[n-col+7]&&d2[n+col])//判断皇后是否冲突
{
place[n]=col;//放置皇后
flag[col]=false;
d1[n-col+7]=false;
d2[n+col]=false;//将该皇后所在的行、列、对角线设置为被占领
if(n<7)
{//当行数小于7时;递归调用下一行
queen(n+1);
}
else//到最后一行时
{
print();
}//调用输出函数
flag[col]=true;//回溯
d1[n-col+7]=true;//回溯也只回溯一行
d2[n+col]=true;
}
}
return number;
}
int main()
{
number=queen(0);//从第0行开始执行
printf("共有%d种摆放方法",number);//输出方法的个数
return 0;
}
回溯—八皇后问题
于 2024-10-10 15:25:36 首次发布