这个问题是个简单的回溯法问题!
在开始写的时候,我没有注意判断条件,只是简单的判断了每次放置的棋子周围的三颗棋子,而正确的应该是判断竖直方向,左斜,右斜几个方向。最后写出来了!
#include<stdio.h>
#include<memory.h>
/*回溯法(探索与回溯法)是一种选优搜索法,按选优条件向前搜索,
以达到目标。但当探索到某一步时,发现原先选择并不优或达不到目标,
就退回一步重新选择,这种走不通就退回再走的技术为回溯法,
而满足回溯条件的某个状态的点称为“回溯点”。*/
int board[9][9];
int locative[9]={0};//locate[i]表示第i行棋子的位置
int count=0;
void print(int n[])
{
int i=1;
for(;i<9;i++)
printf("%d ",locative[i]);
printf("/n");
}
void trav(int i)//i为递归层数,即皇后摆放在棋盘上的列数,当I大于8时,证明已经按要求摆放好了8列,即得到合法布局
{
if(i>8) {print(locative);count++;return ;}
else for(int j=1;j<9;j++)
{
board[i][j]=1;//在第i行第j列摆放棋子
//判断横,左斜,右斜3条直线上是否有棋子;
int s,x1,x2,x3,x4,h1,h2,w1,w2;
int flag=1;
for(s=0;s<9;s++)
{ if(s==i) continue;
if(board[s][j]==1) {flag=0;break;}
}
for(x1=i-1,h1=j-1;x1>0&&h1>0;x1--,h1--)//左斜上
{
if(board[x1][h1]==1) {flag=0;break;}
}
for(x2=j+1,h2=i-1;x2<9&&h2>0;x2++,h2--)//右斜上
{
if(board[h2][x2]==1) {flag=0;break;}
}
for(x3=i+1,w1=j+1;x3<9&&w1<9;x3++,w1++)//右斜下
{
if(board[x3][w1]==1) {flag=0;break;}
}
for(x4=i+1,w2=j-1;x4<9&&w2>0;x4++,w2--)//左斜下
{
if(board[x4][w2]==1) {flag=0;break;}
}
for(int m=1;m<9;m++)
if(locative[m]==j) {flag=0;break;}//如果第j列已有棋子摆放
if(flag){locative[i]=j;trav(i+1);}//记录位置
board[i][j]=0;//撤销棋子
locative[i]=0;//撤销位置记录
}
return ;
}
void main()
{
memset(board[0],0,sizeof(board));
trav(1);
printf("总数为%d",count);
}