从n皇后问题学习DFS(深度优先搜素算法)1

N皇后(又称8皇后)问题 ,是经典的dfs代表问题,其特征是鲜明的回溯与嵌套和形象的放置作为新手向的好问题。

//J-灵活走位_2023贵工程团体程序设计赛(重现赛)@loliconsk (nowcoder.com)

//P1219 [USACO1.5] 八皇后 Checker Challenge - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)


一 核心思想

  n皇后的核心思想在于回溯,是一个“不撞南墙不回头”的典例,回溯的情况分为以下两种:

  1.遍历的i行超过了n(找到了棋盘之外的、继续走下去的方法):这代表这前面的n行都已经走完走顺了,可以继续往下了,已经求出一个解了,所以我们可以进行回溯;

  2.在i小于n的前提下,我们找不到符号条件的下一步:这代表从上一步开始,这个方向之后的所有选择都是死局,没有符号条件要求的,所有我们必须回溯到上一步重新进行选择。

 

示例图:

这是一个4x4大小的棋盘

这是这个棋盘所可以走的方案的逻辑图

 

这是附赠的图例说明

 


二 代码实现

int n, ans;
int col[N], c[N], p[2*N], q[2*N]

void dfs(int i)
{    
  if(i > n) 
  {
    return ;
  }
  for(int j = 1; j <= n; j++ )
  {
    if(c[j] || p[i+j] || q[i-j+n]) continue;
    col[i] = j;
    c[j] = p[i+j] = q[i-j+n] = 1; dfs(i+1);
    c[j] = p[i+j] = q[i-j+n] = 0;
    col[i] = 0;
  }
}

代码说明:

关于数组:col是记录i行j列放置棋子,i作为行,col[N]作为列。之所以斜线p和q需要开两倍的最大值N,是因为记录p和q的下标是通过i+j和i-j+1实现的,它们的最大值可以达到2n或2n-1,所以我们开2N避免边界越界的问题;

关于回溯:回溯的原因之前讲了,但是我们回溯为了不影响下一个选择,所以我们必须做一件事叫做“还原现场”,这就是c[j] = p[i+j] = q[i-j+n] = 0的原因

个人争议:关于col[i] = j是否有必要回溯,这个个人认为除非你的题目要求你打印出棋盘,否则是不需要的,因为你回溯到i行之后,你放置当前的j是必然走不通/走到头的(不然回鸡毛溯),而无论如何,都将从下一个列开始考虑(j+1列),所以无所谓的,因为dfs遍历每个点只遍历一次

 

posted @ 2024-03-20 20:52  王博涵  阅读(121)  评论(0)    收藏  举报