杰拉斯的博客

经典回溯算法问题:九宫格

杰拉斯 杰拉斯 | 时间:2012-12-18, Tue | 23,020 views
编程算法 

九宫格是在81个格子中,要满足以下条件:(1)每个横行和竖列中的9个格子都包含数字1至9,不重复;(2)每个黑色粗实线围住的9个格子都包含数字1至9,不重复。如下表所示:

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

要求找出给定数字的九宫格。

【输入形式】

输入9行9列81个数字,其中0表示要填的数字。

【输出形式】

输出满足条件的九宫格。

【输入样例】

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

【输出样例】

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

代码及思路如下:

  1. #include<stdio.h>
  2.  
  3. bool canFill(int a[9][9], int k, int n){
  4. int i, j, row = k / 9, col = k % 9;
  5. for(i = 0; i < 9; ++i){
  6. if(a[i][col] == n){
  7. return false;
  8. }
  9. }
  10. for(j = 0; j < 9; ++j){
  11. if(a[row][j] == n){
  12. return false;
  13. }
  14. }
  15. for(i = row - row % 3; i < row - row % 3 + 3; ++i){
  16. for(j = col - col % 3; j < col - col % 3 + 3; ++j){
  17. if(a[i][j] == n){
  18. return false;
  19. }
  20. }
  21. }
  22. return true;
  23. }
  24.  
  25. void fill(int a[9][9], int k = 0){
  26. int i, j;
  27. if(k == 81){
  28. for(i = 0; i < 9; ++i){
  29. for(j = 0; j < 9; ++j){
  30. printf("%d ", a[i][j]);
  31. }
  32. printf("\n");
  33. }
  34. return;
  35. }
  36. int row = k / 9, col = k % 9;
  37. if(a[row][col] == 0){
  38. for(i = 1; i <= 9; ++i){
  39. if(canFill(a, k, i)){
  40. a[row][col] = i;
  41. fill(a, k + 1);
  42. a[row][col] = 0;
  43. }
  44. }
  45. }else{
  46. fill(a, k + 1);
  47. }
  48. }
  49.  
  50. int main(){
  51. int i, j, a[9][9];
  52. for(i = 0; i < 9; ++i){
  53. for(j = 0; j < 9; ++j){
  54. scanf("%d", &a[i][j]);
  55. }
  56. }
  57. fill(a);
  58. return 0;
  59. }

2013年5月4日3点温习重写代码如下:

  1. #include<stdio.h>
  2.  
  3. int square[9][9];
  4.  
  5. int isEnabled(int k, int num){
  6. int row = k / 9;
  7. int col = k % 9;
  8. for(int i = 0; i < 9; ++i){
  9. if(square[row][i] == num || square[i][col] == num){
  10. return false;
  11. }
  12. }
  13. int m = row - row % 3;
  14. int n = col - col % 3;
  15. for(int i = m; i < m + 3; ++i){
  16. for(int j = n; j < n + 3; ++j){
  17. if(square[i][j] == num){
  18. return false;
  19. }
  20. }
  21. }
  22. return true;
  23. }
  24.  
  25. void fill(int k = 0){
  26. int row = k / 9;
  27. int col = k % 9;
  28. if(k >= 81){
  29. for(int i = 0; i < 9; ++i){
  30. for(int j = 0; j < 9; ++j){
  31. printf("%d ", square[i][j]);
  32. }
  33. printf("\n");
  34. }
  35. return;
  36. }
  37. if(square[row][col] > 0){
  38. fill(k + 1);
  39. return;
  40. }
  41. for(int i = 1; i <= 9; ++i){
  42. if(isEnabled(k, i)){
  43. square[row][col] = i;
  44. fill(k + 1);
  45. square[row][col] = 0;
  46. }
  47. }
  48. }
  49.  
  50. int main(){
  51. for(int i = 0; i < 9; ++i){
  52. for(int j = 0; j < 9; ++j){
  53. scanf("%d", &square[i][j]);
  54. }
  55. }
  56. fill();
  57. return 0;
  58. }

如需转载请注明出处:杰拉斯的博客

相关文章

2 条评论 »

  1. qwding qwding

    我想问一下,代码放在博客上旁边的行数是怎么弄出来的啊,还有就是代码的那些颜色,谢谢了

    1. 安装代码高亮插件。
      如果你用的是WordPress的话,我的博客里有一款叫CodeColorer的插件还不错:
      http://www.clanfei.com/2012/05/964.html