qq_33825670 2016-06-25 03:05 采纳率: 11.1%
浏览 1710

八皇后问题 回退怎么退

此时要额外注意,所谓的“重新放置”指的并不是将所有皇后清除重新来过,而是只返回上一层,将上一个导致本次放置失败的皇后进行清除,然后重新更新其位置,通过逐级放置、或逐级回溯可以达到遍历所有情况找到所有解
#include
#include

int count=0;//全局计数变量

/*--------------------八个皇后----------------------*/
#define QUEEN_NUM 8
int label[QUEEN_NUM][QUEEN_NUM]={0,0,0,0,
0,0,0,0,
0,0,0,0,
0,0,0,0,
0,0,0,0,
0,0,0,0,
0,0,0,0,
0,0,0,0,
0,0,0,0,
0,0,0,0,
0,0,0,0,
0,0,0,0,
0,0,0,0,
0,0,0,0,
0,0,0,0,
0,0,0,0};

void FillChessbox(int m,int n,int num)
{
for(int i=0;i<QUEEN_NUM;++i)
for(int j=0;j<QUEEN_NUM;++j)
if(abs(i-m)==abs(j-n))//对角区域填充
{
if(label[i][j]==0)
label[i][j]=num;
}

int i=0,j=0;
while(i<QUEEN_NUM)//行填充
{
    if(label[i][n]==0)
        label[i][n]=num;
    ++i;
}
while(j<QUEEN_NUM)//列填充
{
    if(label[m][j]==0)  
        label[m][j]=num;
    ++j;
}

}
void ClearChessBox(int m,int n,int num)
{
for(int i=0;i<QUEEN_NUM;++i)
for(int j=0;j<QUEEN_NUM;++j)
if(abs(i-m)==abs(j-n) && label[i][j]==num)
label[i][j]=0;
int i=0,j=0;
while(i<QUEEN_NUM)
{
if(label[i][n]==num)
label[i][n]=0;
++i;
}
while(j<QUEEN_NUM)
{
if(label[m][j]==num)
label[m][j]=0;
++j;
}
}
void AllClear()
{
for(int i=0;i<QUEEN_NUM;++i)
for(int j=0;j<QUEEN_NUM;++j)
label[i][j]=0;

}
void PrintResult()
{
for(int i=0;i<QUEEN_NUM;++i)
{
for(int j=0;j<QUEEN_NUM;++j)
printf("%d ",label[i][j]);
printf("\n");

}

}
bool EightQueen(int n/*皇后个数*/,int c/*已经放置的皇后个数*/)
{
//static int count=0;
//小于3x3的棋盘是无解的
if(n<4)
return false;

for(int i=0;i<n;++i)
{
    if(label[c-1][i]==0)//存在可以放置第c个皇后的位置
    {
        label[c-1][i]=c+1;
        if(c==n)/*已经放置完毕所有的皇后*/
        {
            ++count;
            PrintResult();
            printf("**************************\n");
            ClearChessBox(c-1,i,c+1);
            //AllClear();
            return true;
        }
        FillChessbox(c-1,i,c+1);
        EightQueen(n,c+1);
        ClearChessBox(c-1,i,c+1);
        /*-------------------------------------------------------------------------------------------------------------------------
        //  现场恢复,无论下一个皇后是否顺利放置,都应该恢复现场。原因是
        //
        //  如果下一个皇后放置失败,那么自然应该将本次放置的皇后去除,重新放置,所以需要进行现场恢复(即回溯);
        //  如果下一个皇后放置成功,意味着本次放置已经满足条件,是一个解,此时需要恢复现场,进行下一次的重新放置,寻找下一个解。
        //
        //------------------------------------------------------------------------------------------------------------------------*/
        //if(!EightQueen(n,c+1))
        //  ClearChessBox(c-1,i,c+1);

    }
}
return false;

}

int main()
{
EightQueen(QUEEN_NUM,1);
printf("%d\n",count);
return 0;
}

所谓的“重新放置”指的并不是将所有皇后清除重新来过,而是只返回上一层,将上一个导致本次放置失败的皇后进行清除,然后重新更新其位置,通过逐级放置、或逐级回溯可以达到遍历所有情况找到所有解

这个回退在代码的哪部分体现啊?

  • 写回答

1条回答 默认 最新

  • lyhoo163 2016-06-25 06:05
    关注

    通过递归方式,自动返回呀。

    评论

报告相同问题?

悬赏问题

  • ¥15 如何用stata画出文献中常见的安慰剂检验图
  • ¥15 c语言链表结构体数据插入
  • ¥40 使用MATLAB解答线性代数问题
  • ¥15 COCOS的问题COCOS的问题
  • ¥15 FPGA-SRIO初始化失败
  • ¥15 MapReduce实现倒排索引失败
  • ¥15 ZABBIX6.0L连接数据库报错,如何解决?(操作系统-centos)
  • ¥15 找一位技术过硬的游戏pj程序员
  • ¥15 matlab生成电测深三层曲线模型代码
  • ¥50 随机森林与房贷信用风险模型