为什么我写的八皇后问题有5242种解法!我看书只有92种解法!

leonliu7558168 2010-09-20 10:29:32
#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列摆放棋子
if(board[i-1][j-1]!=1&&board[i-1][j]!=1&&board[i-1][j+1]!=1)
{
int flag=1;
for(int m=1;m<9;m++)
if(locative[m]==j) {flag=0;break;}//如果第j列已有棋子摆放
if(flag){locative[i]=j;trav(i+1);}//记录位置
}//if
board[i][j]=0;//撤销棋子
locative[i]=0;//撤销位置记录
}
return ;
}


void main()
{
memset(board[0],0,sizeof(board));
trav(1);
printf("总数为%d",count);
}

这是代码,请高手检查一下!看书只有92种解法!
...全文
133 5 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
leonliu7558168 2010-09-20
  • 打赏
  • 举报
回复
额!我知道了!谢谢!应该是横竖斜四条直线!我再改改!
leonliu7558168 2010-09-20
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 void_wuyu 的回复:]

你的判断条件有问题:
if(board[i-1][j-1]!=1&&board[i-1][j]!=1&&board[i-1][j+1]!=1)
你只判断了它的周围3个位置,应该是4条直线.
[/Quote]

应该是哪四条直线?请说明一下?
乐CC 2010-09-20
  • 打赏
  • 举报
回复
还有,楼主你想的太简单了,你的循环只能回溯一步,当你的最后一个棋子放不下去的时候,你需要回溯的步骤可能是N步,所以你的这个方法如果判断条件对了,就有可能出现无解的情况,所以要作特殊处理.
乐CC 2010-09-20
  • 打赏
  • 举报
回复
你的判断条件有问题:
if(board[i-1][j-1]!=1&&board[i-1][j]!=1&&board[i-1][j+1]!=1)
你只判断了它的周围3个位置,应该是4条直线.
leonliu7558168 2010-09-20
  • 打赏
  • 举报
回复
#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);
}

这个对了!谢谢楼上的!

70,023

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧