求解八皇后问题

Love The Way You Lie 2023-09-24 14:27 176阅读 0赞

八皇后问题,是回溯算法的典型案例。

aa79c8d2efcb4470bf497ee70fec8521.png

相比对于大家来说八皇后问题已经知道他的基本要求了,这里再给大家详细阐述一下

(1)列:规定每一列放一个皇后,不会造成列上的冲突;

(2)行:规定每一行放一个皇后,不会造成行上的冲突;

(3)对角线:对角线有两个方向,正对角线和反对角线,每一条正对角线和反对角线只能放一个皇后,不会造成冲突;
这里主要用的是深度优先搜索

深度优先算法:

深度优先搜索算法 (英语: Depth-First-Search , DFS )是一种用于遍历或搜索 树 或 图 的 算法 。. 这个算法会尽可能深的搜索树的分支。. 当节点v的所在边都己被探寻过,搜索将回溯到发现节点v的那条边的起始节点。. 这一过程一直进行到已发现从源节点可达的所有节点为止。. 如果还存在未被发现的节点,则选择其中一个作为源节点并重复以上过程,整个进程反复进行直到所有节点都被访问为止,这种算法不会根据图的结构等信息调整执行策略

基于深度优先搜索,对于八皇后问题,主要代码思想为

当这一列,对应对角线上与反对角线上都没有皇后,则可以在这个位置放皇后

随后标记这一列,对角线,反对角线,表示下一次搜索时不应在这一列,对角线,反对角线放皇后

当问题有解后,则需要恢复原状,重新进行搜索

  1. for(int i=0;i<n;i++){
  2. if(!col[i] && !dg[u+i] && !udg[n-u+i]){
  3. g[u][i]='Q';
  4. col[i]=dg[u+i]=udg[n-u+i]=true;
  5. dfs(u+1);
  6. col[i]=dg[u+i]=udg[n-u+i]=false;
  7. g[u][i]='.';
  8. }
  9. }

完整代码:

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. const int N=20;
  4. int n,t;
  5. char g[N][N];
  6. bool col[N],dg[N],udg[N];//分别为列,正对角线,反对角线
  7. void dfs(int u){
  8. if(u==n){//如果递归到最后一层,也就代表有一个可行性方案,进行输出
  9. for(int i=0;i<n;i++) cout<<g[i]<<endl;
  10. puts("");
  11. t++;
  12. return;
  13. }
  14. for(int i=0;i<n;i++){
  15. if(!col[i] && !dg[u+i] && !udg[n-u+i]){当这一列,对应对角线上与反对角线上都没有皇后
  16. g[u][i]='Q';//则可以在这个位置放皇后,皇后用Q来表示
  17. col[i]=dg[u+i]=udg[n-u+i]=true;
  18. dfs(u+1);//递归到下一层
  19. //搜寻完一个解后,就要会恢复现场,进行下一次寻找
  20. col[i]=dg[u+i]=udg[n-u+i]=false;//恢复现场
  21. g[u][i]='.';//其余地方用.来表示
  22. }
  23. }
  24. }
  25. int main(){
  26. cin>>n;
  27. for(int i=0;i<n;i++){
  28. for(int j=0;j<n;j++){
  29. g[i][j]='.';
  30. }
  31. }
  32. dfs(0);
  33. cout<<t;//输出总共有几个解
  34. return 0;
  35. }

这里的代码是不用关心行上的冲突的,因为row在加1;

这里关于精准找到对角线和反对角线上的点有一个小技巧:上面写到对(i+j)、(i-j)的位置标记为占领状态,对于数组下标来说,肯定都是正的,i-j有可能时负的,所以要加一个偏移量n,这样就不会有负数的存在了。

发表评论

表情:
评论列表 (有 0 条评论,176人围观)

还没有评论,来说两句吧...

相关阅读

    相关 皇后问题

    回溯法求解八皇后问题 n皇后问题:n皇后问题是指在一个n\n的国际象棋棋盘上放置n个皇后,使得这n个皇后两两不在同一行,同一列,同一条对角线上,求合法的方案数。 如

    相关 皇后问题

    即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。 由于皇后们是不能放在同一行的, 所以我们可以去掉“行”这个因素,即我第1次考虑把皇后放在第1行的某

    相关 皇后问题

     在国际象棋中,皇后是最强大的一枚棋子,可以吃掉与其在同一行、列和斜线的敌方棋子.八皇后问题是这样一个问题:将八个皇后摆在一张8\8的国际象棋棋盘上,使每个皇后都无法吃掉别的皇

    相关 皇后问题

            八皇后问题,以国际象棋为背景:如何能够在 8×8 的国际象棋棋盘上放置八个皇后,使得任何一个皇后都无法直接吃掉其他的皇后?为了达到此目的,任意两个皇后都不能处于