递归求解九宫格(数独)源代码

以下是用递归的方式求解九宫格(数独)的源代码:

[cpp] 
view plain
copy

  1. //=========================================================================  
  2. ///////////////////////////////////////////////////////////////////////////  
  3. //[  
  4. //[   Filename:         test.c  
  5. //[   Function:          数独求解  
  6. //[   Last Update:      2012.7.16  
  7. //[   CopyLeft:     Phoenix_Su  
  8. //[        Note:   1.源程序末尾的注释为输入格式,第一个矩阵为区块划分标记(从1开始),  
  9. //[                      如九宫格的划分为注释中所示,第二个矩阵为待填满的九宫格,  
  10. //[                      用你预先设定的数字替换矩阵中的加号即可,第二个矩阵  
  11. //[                      填好后将其复制进文本文件以”in.txt”命名保存至工程的目录下  
  12. //[                   2.注意输入文件”in.txt”中的空格数量不要出错,建议用记事本打开,  
  13. //[                      否则九宫格的形状会很奇葩……  
  14. //[                   3.源代码末尾的注释中的九宫格为芬兰数学家发现的传说中  
  15. //[                      ”最难“的九宫格,仅有一个解!  
  16. //[                   4.暂时只支持小于9的矩阵,若改成大于9*9的矩阵需要将读取方式  
  17. //[                      改成GUI形式,且跟Res数组相关的部分需作相应更改  
  18. //[                      (主要是数据类型的问题导致输入输出方式有一定的变化)  
  19. //[  
  20. ///////////////////////////////////////////////////////////////////////////  
  21. //=========================================================================  
  22.   
  23. #include <stdio.h>  
  24. #include <stdlib.h>  
  25. #include <string.h>  
  26. #include <ctype.h>  
  27. #include <conio.h>  
  28. #include <time.h>  
  29. #include <assert.h>  
  30.   
  31. #define  WIDTH  9  
  32. #define  HIGHT   9  
  33. #define  REC_WIDTH ((WIDTH)*2)   // 18  char number of each line  
  34. #define  BUF_SIZE    (REC_WIDTH)  // 18  
  35. #define  BLOCK_SIZE  9  
  36. #define  BLOCK_NUM  ((WIDTH)*(HIGHT)/(BLOCK_SIZE))  //9  
  37. #define  USED  1  
  38. #define  UNUSED  0  
  39. #define  FIND_SOLUTION 1  
  40.   
  41. int ReadMatrix( void );  
  42. void SolveMatrix( int line , int column , int block );  
  43. void FillNextBox( int line , int column );  
  44. void DisplaySolution();  
  45.   
  46. int IfSolved;  //0 for unsolved , 1 for solved  
  47. int BlockState[BLOCK_NUM][BLOCK_SIZE];  // 1 for has been used  
  48. int LineState[HIGHT][WIDTH];  // 1 for has been used  
  49. int ColumnState[WIDTH][HIGHT];  // 1 for has been used  
  50. char Res[WIDTH][HIGHT];    // record resolution  
  51. int BoxAttr[HIGHT][WIDTH]; // decide each box belongs to which block  
  52.   
  53. int main( void )  
  54. {  
  55.    time_t StartTime , EndTime ;  
  56.   
  57.    assert( WIDTH*HIGHT == BLOCK_SIZE*BLOCK_NUM );  
  58.   
  59.    if( ReadMatrix() == EOF )  
  60.    {  
  61.       printf( “Can not find the file. Press any key to exit.” );  
  62.       getch();  
  63.       return 0;  
  64.    }  
  65.   
  66.    StartTime = clock();  
  67.    SolveMatrix( 0 , 0 , 0 );  
  68.    EndTime = clock();  
  69.   
  70.    if( IfSolved != FIND_SOLUTION )  
  71.    {  
  72.       printf( “Can not find a solution!” );  
  73.    }  
  74.    printf( “Cost : %d ms , Press any key to exit…” , EndTime – StartTime );  
  75.    getch();  
  76.   
  77.    return 0;  
  78. }  
  79.   
  80. int ReadMatrix( void )  
  81. {  
  82.    int l = 0 , c , c2 ;   // count for lines , columns  
  83.    int number; //record the number in the matrix  
  84.    char buf[BUF_SIZE];  //buffer for read the matrix line by line  
  85.    FILE *pf;  
  86.   
  87.    if( ( pf = fopen( “in.txt” , “r” ) ) == NULL )  
  88.    {  
  89.       return EOF;  
  90.    }  
  91.   
  92.    //read the box attribute from file  
  93.    for( l = 0 ; l < HIGHT ; l++ )  
  94.    {  
  95.       fgets( buf , REC_WIDTH , pf );  
  96.       for( c = 0 , c2 = 0 ; c < WIDTH ; c++ , c2 += 2 )  
  97.       {  
  98.          BoxAttr[l][c] = buf[c2] – ‘1’;  
  99.       }  
  100.       fgetc( pf );  //read the ‘\r’  
  101.    }  
  102.   
  103.    //read the matrix from file  
  104.    for( l = 0 ; l < HIGHT ; l++ )  
  105.    {  
  106.       fgetc( pf );  //read the ‘\r’  
  107.       fgets( buf , REC_WIDTH , pf );  
  108.       for( c = 0 , c2 = 0 ; c < WIDTH ; c++ , c2 += 2 )  
  109.       {  
  110.          if( isdigit( buf[c2] ) )  
  111.          {  
  112.             number = buf[c2] – ‘1’;  
  113.             Res[l][c] = buf[c2];  
  114.             LineState[l][number] = USED;  
  115.             ColumnState[c][number] = USED;  
  116.             BlockState[BoxAttr[l][c]][number] = USED;  
  117.          }  
  118.       }  
  119.    }  
  120.   
  121.    fclose( pf );  
  122.    return 0;  
  123. }  
  124.   
  125. void SolveMatrix( int line , int column , int block )  
  126. {  
  127.    int i = 0;  
  128.    if( Res[line][column] == 0 )  
  129.    {  //current box has not been filled yet , fill it  
  130.       for( ; i < WIDTH ; i++ )  
  131.       {  
  132.          if(      ( LineState[line][i] == 0 )   
  133.             && ( ColumnState[column][i] == 0 )  
  134.             && ( BlockState[block][i] == 0 ) )  
  135.          {  
  136.             Res[line][column] = ‘1’ + i ;  
  137.             LineState[line][i] = USED;  
  138.             ColumnState[column][i] = USED;  
  139.             BlockState[block][i] = USED;  
  140.   
  141.             FillNextBox( line , column );  
  142.   
  143.             Res[line][column] = UNUSED ;  
  144.             LineState[line][i] = UNUSED;  
  145.             ColumnState[column][i] = UNUSED;  
  146.             BlockState[block][i] = UNUSED;  
  147.          }  
  148.       }        
  149.    }  
  150.    else  
  151.    {  //current box has been filled , check next box  
  152.       FillNextBox( line , column );  
  153.    }  
  154. }  
  155.   
  156. void FillNextBox( int line , int column )  
  157. {  
  158.    if( column == (WIDTH-1) )  
  159.    {    
  160.       if( line != (HIGHT-1) )  
  161.       {  //finished a line ,fill next line  
  162.          SolveMatrix( line+1 , 0 , BoxAttr[line+1][0] );  
  163.       }  
  164.       else  
  165.       {  //all finished and get a solution  
  166.          DisplaySolution();  
  167.          IfSolved = FIND_SOLUTION;  
  168.       }  
  169.    }  
  170.    else  
  171.    {  //fill next column  
  172.       SolveMatrix( line , column+1 , BoxAttr[line][column+1] );  
  173.    }  
  174. }  
  175.   
  176. void DisplaySolution( void )  
  177. {  
  178.    int line = 0 , column;  
  179.    for( ; line < HIGHT ; line++ )  
  180.    {  
  181.       for( column = 0 ; column < WIDTH ; column++ )  
  182.       {  
  183.          putchar( Res[line][column] );  
  184.          putchar( ‘ ‘ );  
  185.          if( ((column+1)%3) == 0 )  
  186.          {  
  187.             putchar( ‘ ‘ );  
  188.          }  
  189.       }  
  190.       if( ((line+1)%3) == 0 )  
  191.       {  
  192.          putchar( ‘\n’ );  
  193.       }  
  194.       putchar( ‘\n’ );  
  195.    }  
  196.    puts( “——————————“ );  
  197. }  
  198.   
  199. /* 
  200. ========[input example start]========== 
  201. 1 1 1 2 2 2 3 3 3 
  202. 1 1 1 2 2 2 3 3 3 
  203. 1 1 1 2 2 2 3 3 3 
  204. 4 4 4 5 5 5 6 6 6 
  205. 4 4 4 5 5 5 6 6 6 
  206. 4 4 4 5 5 5 6 6 6 
  207. 7 7 7 8 8 8 9 9 9 
  208. 7 7 7 8 8 8 9 9 9 
  209. 7 7 7 8 8 8 9 9 9 
  210.  
  211. 8 + + + + + + + + 
  212. + + 3 6 + + + + + 
  213. + 7 + + 9 + 2 + + 
  214. + 5 + + + 7 + + + 
  215. + + + + 4 5 7 + + 
  216. + + + 1 + + + 3 + 
  217. + + 1 + + + + 6 8 
  218. + + 8 5 + + + 1 + 
  219. + 9 + + + + 4 + + 
  220.  
  221. ========[input example end]========= 
  222. 请忽略下面的信息。 
  223. ===========[empty box]=========== 
  224. + + + + + + + + + 
  225. + + + + + + + + + 
  226. + + + + + + + + + 
  227. + + + + + + + + + 
  228. + + + + + + + + + 
  229. + + + + + + + + + 
  230. + + + + + + + + + 
  231. + + + + + + + + + 
  232. + + + + + + + + + 
  233.  
  234. int BoxAttr[HIGHT][WIDTH] = { 
  235. 0 , 0 , 0   ,   1 , 1 , 1   ,   2 , 2 , 2   , 
  236. 0 , 0 , 0   ,   1 , 1 , 1   ,   2 , 2 , 2   , 
  237. 0 , 0 , 0   ,   1 , 1 , 1   ,   2 , 2 , 2   , 
  238.  
  239. 3 , 3 , 3   ,   4 , 4 , 4   ,   5 , 5 , 5   ,    
  240. 3 , 3 , 3   ,   4 , 4 , 4   ,   5 , 5 , 5   ,    
  241. 3 , 3 , 3   ,   4 , 4 , 4   ,   5 , 5 , 5   ,    
  242.  
  243. 6 , 6 , 6   ,   7 , 7 , 7   ,   8 , 8 , 8   , 
  244. 6 , 6 , 6   ,   7 , 7 , 7   ,   8 , 8 , 8   , 
  245. 6 , 6 , 6   ,   7 , 7 , 7   ,   8 , 8 , 8    
  246. }; 
  247. ============================== 
  248.  
  249. */  

《递归求解九宫格(数独)源代码》

    原文作者:九宫图算法
    原文地址: https://blog.csdn.net/phoenix_szx/article/details/7791096
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞