当前位置:   article > 正文

华为机试HJ44:Sudoku(数独问题,深度优先遍历DFS解法)_hj44 sudoku js

hj44 sudoku js

作者:翟天保Steven
版权声明:著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处

题目描述:

问题描述:数独(Sudoku)是一款大众喜爱的数字逻辑游戏。玩家需要根据9X9盘面上的已知数字,推算出所有剩余空格的数字,并且满足每一行、每一列、每一个3X3粗线宫内的数字均含1-9,并且不重复。

例如:

输入

输出

输入描述:

包含已知数字的9X9盘面数组[空缺位以数字0表示]

输出描述:

完整的9X9盘面数组

示例:

输入:

  1. 0 9 2 4 8 1 7 6 3
  2. 4 1 3 7 6 2 9 8 5
  3. 8 6 7 3 5 9 4 1 2
  4. 6 2 4 1 9 5 3 7 8
  5. 7 5 9 8 4 3 1 2 6
  6. 1 3 8 6 2 7 5 9 4
  7. 2 7 1 5 3 8 6 4 9
  8. 3 8 6 9 1 4 2 5 7
  9. 0 4 5 2 7 6 8 3 1

输出:

  1. 5 9 2 4 8 1 7 6 3
  2. 4 1 3 7 6 2 9 8 5
  3. 8 6 7 3 5 9 4 1 2
  4. 6 2 4 1 9 5 3 7 8
  5. 7 5 9 8 4 3 1 2 6
  6. 1 3 8 6 2 7 5 9 4
  7. 2 7 1 5 3 8 6 4 9
  8. 3 8 6 9 1 4 2 5 7
  9. 9 4 5 2 7 6 8 3 1

解题思路:

本题是数独问题,采用深度优先遍历法,一个个输入,若某个点没有合适数值,则返回到上个点重新找合适点,直到所有点都完美填充。

VaildExist函数用来判断该位置是否能放置数值m,数独中某行某列某个3*3的方针不能有重复数字;Find函数找寻数独表中的下一个0点位置,将row和col刷新,若没0点了,则说明填充完毕了;DFS是深度优先遍历法的主函数,用flag表示当前数据填充是否合适,col满9则row进1,即进入下一行,用Find判断还有0点没,若还有,则将row和col刷新到最近的0点位置,然后1-9依次填充,若有合适值填充进去,则继续执行DFS,DFS如果返回的是错误结果,那之前填充的数值要换掉,继续找下一个合适的,若找完都没有合适的,就再返回到上一个填充数的位置并进行数值更换,以此类推,直到某次DFS返回的是true,则表示完成数独表的填充。

测试代码:

  1. #include<iostream>
  2. #include<vector>
  3. #include<string>
  4. using namespace std;
  5. // 判断该位置是否能放置m,即同行同列同3*3方阵是否存在m
  6. bool ValidExist(vector<vector<int>> sudoku, int i, int j, int m)
  7. {
  8. //判断所在行
  9. for (int k = 0; k < 9; ++k)
  10. {
  11. if (sudoku[i][k] == m)
  12. return false;
  13. }
  14. //判断所在列
  15. for (int k = 0; k < 9; ++k)
  16. {
  17. if (sudoku[k][j] == m)
  18. return false;
  19. }
  20. //判断所在3*3方阵
  21. int Lrow = i / 3 * 3;
  22. int Lcol = j / 3 * 3;
  23. for (int row = Lrow; row < Lrow + 3; ++row)
  24. for (int col = Lcol; col < Lcol + 3; ++col)
  25. {
  26. if (sudoku[row][col] == m)
  27. return false;
  28. }
  29. return true;
  30. }
  31. // 找寻数独表的0
  32. bool Find(vector<vector<int>> sudoku, int &row, int &col)
  33. {
  34. int i, j;
  35. while (row < 9 && col < 9)
  36. {
  37. if (sudoku[row][col] == 0)
  38. return true;
  39. else
  40. {
  41. col++;
  42. if (col == 9)
  43. {
  44. col = 0;
  45. row++;
  46. }
  47. }
  48. }
  49. return false;
  50. }
  51. // 深度优先遍历法
  52. bool DFS(vector<vector<int>> &sudoku, int row, int col)
  53. {
  54. bool flag = false;
  55. if (col > 8)
  56. {
  57. col = col % 9;
  58. row++;
  59. }
  60. // 如果没有0点了,则表示完成了填充
  61. if (!Find(sudoku, row, col))
  62. return true;
  63. //1开始赋值,若填写某个数值后,其他0点位置无法找到合适值,则数值递进再次尝试
  64. for (int m = 1; m <= 9; m++)
  65. {
  66. if (ValidExist(sudoku, row, col, m))
  67. {
  68. sudoku[row][col] = m;
  69. flag= DFS(sudoku, row, col+1);
  70. if (flag == false)
  71. continue;
  72. else
  73. return true;
  74. }
  75. }
  76. // 若没有合适值,将当前位置置0,返回false,使上个填充数据再更换其他数值尝试
  77. if (flag == false)
  78. {
  79. sudoku[row][col] = 0;
  80. return false;
  81. }
  82. }
  83. int main()
  84. {
  85. vector<vector<int>> sudoku(9, vector<int>(9, 0));
  86. for (int i = 0; i < 9; ++i)
  87. for (int j = 0; j < 9; ++j)
  88. cin >> sudoku[i][j];
  89. DFS(sudoku, 0, 0);
  90. for (int i = 0; i < 9; ++i)
  91. {
  92. for (int j = 0; j < 9; ++j)
  93. cout << sudoku[i][j] << " ";
  94. cout << endl;
  95. }
  96. return 0;
  97. }
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小小林熬夜学编程/article/detail/434322
推荐阅读
相关标签
  

闽ICP备14008679号

        
cppcmd=keepalive&