1)问题描述
- 按行来放皇后,从0~7
- 每一行可放0~7中的一列,一个位置
- 但是皇后,不能在同一对角线上(左,右),不能再同一列,同一行。
2)算法描述
- 用col来存储对应列,已存的 j 列col[j]=1
- 用left来存储左斜线,已占的斜线left[i+j]=1
- 用right来存储右斜线,已占的斜线right[7+i-j]=1
- Q来遍历每一行时, i 行用Q[i](栈)来存储 j 列
3)代码描述
①用栈来描述
#include<stdio.h>
int Q[8];//放行和列
int col[8]={0};//将其初始化为零,表示列没有被占
int left[15]={0};//将其初始化为零,表示左斜线没有被占
int right[15]={0};//将其初始化为零,表示右斜线没有被占
int cnt=0;//计数
//输出Queen
void PrintQueen()
{
printf("\n\n");
printf("%2d:\n",++cnt);
int i,j;
for(i=0;i<8;i++)
{
for(j=0;j<8;j++)
{
if(Q[i]==j)
printf("%2d",Q[i]);
else
printf("%2c",'x');
}
printf("\n");
}
}
//放皇后
void Queen()
{
int i=0,j=0;//i为行,j为列
while(i<8)
{
for(;j<8;j++)//遍列可填的列
{
if(!col[j] && !left[i+j] && !right[7+i-j])//满足的条件的列
{
Q[i]=j;//放皇后
col[j]=left[i+j]=right[7+i-j]=1;//相应的一占
i++;
j=0;
if(i==8)//找到一个符合输出
{
PrintQueen();
j=8;
}
break;
}
}
if(j==8)//回朔
{
j=Q[--i];
col[j]=left[i+j]=right[7+i-j]=0;
j++;
}
}
}
int main(void)
{
Queen();
return 0;
}
②用递归来描述
#include<stdio.h>
int Q[8];
int col[8]={0};//将其初始化为零,表示列没有被占
int left[15]={0};//将其初始化为零,表示左斜线没有被占
int right[15]={0};//将其初始化为零,表示右斜线没有被占
int cnt=0;//计数
//输出Queen
void PrintQueen()
{
printf("\n\n");
printf("%2d:\n",++cnt);
int i,j;
for(i=0;i<8;i++)
{
for(j=0;j<8;j++)
{
if(Q[i]==j)
printf("%2d",Q[i]);
else
printf("%2c",'x');
}
printf("\n");
}
}
//放皇后
void Queen(int i)
{
int j;
for(j=0;j<8;j++)
{
if(!col[j] && !left[i+j] && !right[7+i-j])
{
Q[i]=j;
col[j]=left[i+j]=right[7+i-j]=1;
if(i<7)
Queen(i+1);//继续往后放
else
PrintQueen();//放满就输出
col[j]=left[i+j]=right[7+i-j]=0;//回朔回来
}
}
}
int main(void)
{
Queen(0);
return 0;
}