八皇后问题的新手解答(目前还有一个问题没有)

总体思路

以列为例,每一列从第一行遍历一遍,没有危险的地方就可以放一个皇后。这个问题涉及到的小问题有几个:
1、如何判断是否安全
2、如果不安全,如何回溯
3、如何输出之后重新来一遍

整体细节

问题一

递归函数应该怎么写?
思路是,从第一列开始每一个位置遍历,然后遇到可以放皇后的位置就移向下一列,说明我们需要向函数传递表示列的参数,并且在函数内部需要一个循环来遍历8行的位置;而且调用函数的语句显然是放在循环内部,即在某一行放了一个皇后之后就进行下一列。
如何判断这个位置是否安全?
如果遍历这个位置的行与列,复杂度将会变高(每一行、每一列、两条斜线都要遍历一遍),那么可以定义四个数组,分别代表行,列,两条斜线,每个数组的里面的数代表这一行(列、斜线)是否安全,如,用1表示安全,用0表示不安全,那么初始化为1,然后放好一个皇后之后要更新它所在的行列与斜线

问题二

需要回溯的情况
如果所在的行列与斜线都不安全,而且这一列没有地方可以放皇后,就需要回溯。回溯的结果是回到上一列,将刚才放置皇后的位置初始化,然后换下一个安全的位置放皇后。
回溯的语句放在哪里?
根据回溯的条件,我们需要在循环到最后一行也不能放皇后的时候回溯,因此,我们在循环行完毕之后进行回溯。
回溯要做些什么?
将棋盘和行数组元素、列数组元素、两条斜线数组元素初始化。然后需要返回上一个被调用的函数。

问题三

如何输出
可以在定义一个函数用来输出。注意输出格式与空格。

void print()
{
 for (int i = 0; i < 8; i++)
 {
  for (int j = 0; j < 8; j++)
  {
   if (j < 7)//非最后一个格子 
   {
    if (board[i][j] == 0)
     cout << "." << " ";//没有皇后 
    else
     cout << "*" << " ";//放置皇后 
   }
   else//最后一个格子 
   {
    if (board[i][j] == 0)
     cout << ".";
    else
     cout << "*";
   }
  }
  cout << endl;
 }
}//输出表格 

在哪里输出?
如果每一列都有皇后了,即函数的参数已经到最后一列并且放好了皇后,那么就可以输出。
在函数的一开始判断传递进来的参数的大小,如果是最后一列已经放好了,就可以输出答案标号和棋盘了。
输出之后如何进行下一步的探索?
输出后回到上一个被调用的函数,然后就可以正常进行接下来的遍历了。

递归函数片段(有一个地方还没有想到比较好的解决办法)

void f(int column)
{
 if (p <= 92)//就是这个地方
 if (column < 8)
 {
  for (int i = 0; i < 8; i++)
  {
   if (!row[i] && !col[column] && !Left[i+column] && !Right[7+i-column])//如果这个点是安全的,就可以放 
   {
    row[i] = 1;
    col[column] = 1;
    Left[i+column] = 1;
    Right[7+i-column] = 1;
    board[i][column] = 1;//更新数据 
    f(column+1);
    board[i][column] = 0;
    row[i] = 0;
    col[column] = 0;
    Left[i+column] = 0;
    Right[7+i-column] = 0;//回溯 
   }
  }
 }
 else
 {
  cout << p << endl;
  print();
  p++;//输出标号 
 } 
} 

由于八皇后问题有92解,然后我暂时没有想到可以在9解之后结束输出的办法,就只好用p<=92来结束。实际上,如果没有这个条件控制的话,那么程序会输出第一列没有放皇后的棋盘,第二列没有放皇后的棋盘……

关于整个代码

没有什么好说的,要注意的问题也就是先定义输出棋盘的函数,因为在递归函数里面要调用输出函数;然后主要的变量都是定义成全局变量。主函数如下:

int main()
{
 for (int k = 0; k < 8; k++)
 {
  f(k);//将列参数传递进去
 }
 return 0;
}

写在最后

这是智障博主的第一篇博客,然后也不是很专业。毕竟智障博主才学c++不到三个月,写这个只是为了智障博主以后复习c++。也请大家不要嫌弃,然后有优秀的小伙伴可以帮忙想一下那个问题呗,给大家坐下了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我可以用中文回答您的问题。 如果您想用Python写一个八皇后问题的解决程序,可以按照以下步骤进行: 1. 定义棋盘大小 首先需要定义棋盘的大小,这里我们定义为一个常量n。八皇后问题是指在一个8x8的棋盘上放置8个皇后,所以这里n为8。 2. 定义冲突检测函数 八皇后问题的核心是如何检测皇后的位置是否合法。我们可以定义一个函数来检测冲突,函数接收两个参数,分别是当前皇后的位置(row, col)和之前皇后的位置列表(queens)。函数需要遍历之前的每一个皇后,判断当前皇后和之前的皇后是否在同一行、同一列或者同一斜线上。如果在同一行、同一列或者同一斜线上,说明当前皇后的位置不合法。 3. 定义回溯函数 接下来需要定义回溯函数,函数接收一个参数表示当前皇后的位置。如果当前皇后的位置合法,将其添加到皇后位置列表中,然后继续向下递归。如果当前皇后的位置不合法,直接返回。 回溯函数需要遍历每一个列,逐一判断皇后是否可以放置在当前列上。如果可以放置,调用递归函数处理下一个皇后。如果不能放置,继续尝试下一列。 4. 定义主函数 最后定义一个主函数,调用回溯函数解决八皇后问题。在主函数中定义一个长度为n的列表queens,用于存储皇后的位置。然后从第一列开始尝试放置皇后,调用回溯函数解决问题。 当回溯函数返回时,如果queens列表中包含了n个皇后的位置,说明问题已经得到解决。否则,问题无解。 下面是一份Python代码示例,供参考: ```python n = 8 # 冲突检测函数 def conflict(row, col, queens): for r, c in queens: if row == r or col == c or row+col == r+c or row-col == r-c: return True return False # 回溯函数 def backtrack(row, queens): if len(queens) == n: print(queens) return for col in range(n): if not conflict(row, col, queens): queens.append((row, col)) backtrack(row+1, queens) queens.pop() # 主函数 def solve(): queens = [] for col in range(n): queens.append((0, col)) backtrack(1, queens) queens.pop() # 调用主函数解决问题 solve() ``` 希望这个回答能够帮助您解决问题

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值