【数据结构】N皇后(递归经典算法)

爱被打了一巴掌 2022-05-16 13:07 322阅读 0赞

一、N皇后

1、题目
将n个皇后摆放在N*N的棋盘中,互相不可攻击,有多少种摆放方式,每种摆放方式具体是怎样的?

2、解题思路
解题思路:
1、将棋盘放在一个二维数组中,同时设置方向数组:
static const int dx[] = {-1,1,0,0,-1,-1,1,1,};
static const int dy[] = {-1,0,-1,1,-1,1,-1,1};
分别按照方向数组的8个方向分别延伸N个问题,只要不超过边界,mark[][] = 1;其余为0;
2、对于N*N的棋盘,每行都要放置1个且只能放置1个皇后,利用递归对棋盘的每一行放置皇后,放置时,按列顺序寻找可以放置皇后的列,若可以放置皇后,将皇后放置该位置,并更新mark标记数组,递归进行下一行皇后放置,当该次递归结束后,恢复mark数组,并尝试下一个可能放皇后的列;当递归可以完成N列的N个皇后放置,则将该结果保存并返回。
3、棋盘的设置与皇后的放置
70

4、N皇后回溯算法
70 1
5、程序实现

  1. #include<iostream>
  2. #include<vector>
  3. using namespace std;
  4. void put_down_the_queue(int x, int y,
  5. std::vector<std::vector<int>>& mark)
  6. {
  7. static const int dx[] = {-1,1,0,0,-1,-1,1,1};
  8. static const int dy[]= {0,0,-1,1,-1,1,-1,1};
  9. mark[x][y] = 1;
  10. for(int i = 1;i< mark.size();i++)
  11. {
  12. for(int j = 0; j < 8; j++)
  13. {
  14. int new_x = x + i*dx[j];//*********************
  15. int new_y = y + i*dy[j];//**********************
  16. if( (new_x>=0 && new_x<mark.size()) && (new_y >=0&&new_y<mark.size()) )//注意>=********************
  17. {
  18. mark[new_x][new_y] = 1;
  19. }
  20. }
  21. }
  22. }
  23. class solution
  24. {
  25. public:
  26. std::vector<std::vector<std::string>> solveNQuess(int n)
  27. {
  28. std::vector<std::vector<std::string>> result;
  29. std::vector<std::vector<int>> mark;
  30. std::vector<std::string> location;
  31. for(int i = 0;i<n;i++)
  32. {
  33. mark.push_back(std::vector<int>());
  34. for(int j = 0; j <n;j++)
  35. {
  36. mark[i].push_back(0);
  37. }
  38. location.push_back("");
  39. location[i].append(n,'.');
  40. }
  41. generate(0,n,location,result,mark);
  42. return result;
  43. }
  44. private:
  45. void generate(int k, int n,
  46. std::vector<std::string>&location,
  47. std::vector<std::vector<std::string>>&result,
  48. std::vector<std::vector<int>> &mark
  49. )
  50. {
  51. if(k == n)
  52. {
  53. result.push_back(location);
  54. return ;
  55. }
  56. for(int i = 0; i<n; i++)
  57. {
  58. if(mark[k][i] == 0)
  59. {
  60. std::vector<std::vector<int>> tmp_mark = mark;
  61. location[k][i] = 'Q';
  62. put_down_the_queue(k,i,mark);
  63. generate(k+1, n, location,result,mark);
  64. mark = tmp_mark;
  65. location[k][i] = '.';
  66. }
  67. }
  68. }
  69. };
  70. int main()
  71. {
  72. std::vector<std::vector<std::string>> result;
  73. solution solve;
  74. result = solve.solveNQuess (4);
  75. for(int i = 0; i<result.size();i++)
  76. {
  77. printf("i = %d\n",i);
  78. for(int j = 0; j<result[i].size();j++)
  79. {
  80. printf("%s\n",result[i][j].c_str() );
  81. }
  82. printf("\n");
  83. }
  84. return 0;
  85. }

6、结果展示
70 2

发表评论

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

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

相关阅读

    相关 ---n皇后问题

    题目描述: 在 n x n 的棋盘上面所有的皇后不能相互攻击,即所有的皇后 既不在同一行、不在同一列,也不在同一对角线,如下图所示(以 4 x 4 的棋盘举例): !

    相关 N皇后经典回溯算法

    N皇后题目: 给你一个N\N的棋盘,放置N个皇后,让皇后之间不攻击;攻击规则:皇后可攻击同行、同列、对角线上的所有皇后。 题目分析:如果没有对角线限制,那么这道题就是一个