以下是用递归的方式求解九宫格(数独)的源代码:
[cpp]
view plain
copy
- //=========================================================================
- ///////////////////////////////////////////////////////////////////////////
- //[
- //[ Filename: test.c
- //[ Function: 数独求解
- //[ Last Update: 2012.7.16
- //[ CopyLeft: Phoenix_Su
- //[ Note: 1.源程序末尾的注释为输入格式,第一个矩阵为区块划分标记(从1开始),
- //[ 如九宫格的划分为注释中所示,第二个矩阵为待填满的九宫格,
- //[ 用你预先设定的数字替换矩阵中的加号即可,第二个矩阵
- //[ 填好后将其复制进文本文件以”in.txt”命名保存至工程的目录下
- //[ 2.注意输入文件”in.txt”中的空格数量不要出错,建议用记事本打开,
- //[ 否则九宫格的形状会很奇葩……
- //[ 3.源代码末尾的注释中的九宫格为芬兰数学家发现的传说中
- //[ ”最难“的九宫格,仅有一个解!
- //[ 4.暂时只支持小于9的矩阵,若改成大于9*9的矩阵需要将读取方式
- //[ 改成GUI形式,且跟Res数组相关的部分需作相应更改
- //[ (主要是数据类型的问题导致输入输出方式有一定的变化)
- //[
- ///////////////////////////////////////////////////////////////////////////
- //=========================================================================
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <ctype.h>
- #include <conio.h>
- #include <time.h>
- #include <assert.h>
- #define WIDTH 9
- #define HIGHT 9
- #define REC_WIDTH ((WIDTH)*2) // 18 char number of each line
- #define BUF_SIZE (REC_WIDTH) // 18
- #define BLOCK_SIZE 9
- #define BLOCK_NUM ((WIDTH)*(HIGHT)/(BLOCK_SIZE)) //9
- #define USED 1
- #define UNUSED 0
- #define FIND_SOLUTION 1
- int ReadMatrix( void );
- void SolveMatrix( int line , int column , int block );
- void FillNextBox( int line , int column );
- void DisplaySolution();
- int IfSolved; //0 for unsolved , 1 for solved
- int BlockState[BLOCK_NUM][BLOCK_SIZE]; // 1 for has been used
- int LineState[HIGHT][WIDTH]; // 1 for has been used
- int ColumnState[WIDTH][HIGHT]; // 1 for has been used
- char Res[WIDTH][HIGHT]; // record resolution
- int BoxAttr[HIGHT][WIDTH]; // decide each box belongs to which block
- int main( void )
- {
- time_t StartTime , EndTime ;
- assert( WIDTH*HIGHT == BLOCK_SIZE*BLOCK_NUM );
- if( ReadMatrix() == EOF )
- {
- printf( “Can not find the file. Press any key to exit.” );
- getch();
- return 0;
- }
- StartTime = clock();
- SolveMatrix( 0 , 0 , 0 );
- EndTime = clock();
- if( IfSolved != FIND_SOLUTION )
- {
- printf( “Can not find a solution!” );
- }
- printf( “Cost : %d ms , Press any key to exit…” , EndTime – StartTime );
- getch();
- return 0;
- }
- int ReadMatrix( void )
- {
- int l = 0 , c , c2 ; // count for lines , columns
- int number; //record the number in the matrix
- char buf[BUF_SIZE]; //buffer for read the matrix line by line
- FILE *pf;
- if( ( pf = fopen( “in.txt” , “r” ) ) == NULL )
- {
- return EOF;
- }
- //read the box attribute from file
- for( l = 0 ; l < HIGHT ; l++ )
- {
- fgets( buf , REC_WIDTH , pf );
- for( c = 0 , c2 = 0 ; c < WIDTH ; c++ , c2 += 2 )
- {
- BoxAttr[l][c] = buf[c2] – ‘1’;
- }
- fgetc( pf ); //read the ‘\r’
- }
- //read the matrix from file
- for( l = 0 ; l < HIGHT ; l++ )
- {
- fgetc( pf ); //read the ‘\r’
- fgets( buf , REC_WIDTH , pf );
- for( c = 0 , c2 = 0 ; c < WIDTH ; c++ , c2 += 2 )
- {
- if( isdigit( buf[c2] ) )
- {
- number = buf[c2] – ‘1’;
- Res[l][c] = buf[c2];
- LineState[l][number] = USED;
- ColumnState[c][number] = USED;
- BlockState[BoxAttr[l][c]][number] = USED;
- }
- }
- }
- fclose( pf );
- return 0;
- }
- void SolveMatrix( int line , int column , int block )
- {
- int i = 0;
- if( Res[line][column] == 0 )
- { //current box has not been filled yet , fill it
- for( ; i < WIDTH ; i++ )
- {
- if( ( LineState[line][i] == 0 )
- && ( ColumnState[column][i] == 0 )
- && ( BlockState[block][i] == 0 ) )
- {
- Res[line][column] = ‘1’ + i ;
- LineState[line][i] = USED;
- ColumnState[column][i] = USED;
- BlockState[block][i] = USED;
- FillNextBox( line , column );
- Res[line][column] = UNUSED ;
- LineState[line][i] = UNUSED;
- ColumnState[column][i] = UNUSED;
- BlockState[block][i] = UNUSED;
- }
- }
- }
- else
- { //current box has been filled , check next box
- FillNextBox( line , column );
- }
- }
- void FillNextBox( int line , int column )
- {
- if( column == (WIDTH-1) )
- {
- if( line != (HIGHT-1) )
- { //finished a line ,fill next line
- SolveMatrix( line+1 , 0 , BoxAttr[line+1][0] );
- }
- else
- { //all finished and get a solution
- DisplaySolution();
- IfSolved = FIND_SOLUTION;
- }
- }
- else
- { //fill next column
- SolveMatrix( line , column+1 , BoxAttr[line][column+1] );
- }
- }
- void DisplaySolution( void )
- {
- int line = 0 , column;
- for( ; line < HIGHT ; line++ )
- {
- for( column = 0 ; column < WIDTH ; column++ )
- {
- putchar( Res[line][column] );
- putchar( ‘ ‘ );
- if( ((column+1)%3) == 0 )
- {
- putchar( ‘ ‘ );
- }
- }
- if( ((line+1)%3) == 0 )
- {
- putchar( ‘\n’ );
- }
- putchar( ‘\n’ );
- }
- puts( “——————————“ );
- }
- /*
- ========[input example start]==========
- 1 1 1 2 2 2 3 3 3
- 1 1 1 2 2 2 3 3 3
- 1 1 1 2 2 2 3 3 3
- 4 4 4 5 5 5 6 6 6
- 4 4 4 5 5 5 6 6 6
- 4 4 4 5 5 5 6 6 6
- 7 7 7 8 8 8 9 9 9
- 7 7 7 8 8 8 9 9 9
- 7 7 7 8 8 8 9 9 9
- 8 + + + + + + + +
- + + 3 6 + + + + +
- + 7 + + 9 + 2 + +
- + 5 + + + 7 + + +
- + + + + 4 5 7 + +
- + + + 1 + + + 3 +
- + + 1 + + + + 6 8
- + + 8 5 + + + 1 +
- + 9 + + + + 4 + +
- ========[input example end]=========
- 请忽略下面的信息。
- ===========[empty box]===========
- + + + + + + + + +
- + + + + + + + + +
- + + + + + + + + +
- + + + + + + + + +
- + + + + + + + + +
- + + + + + + + + +
- + + + + + + + + +
- + + + + + + + + +
- + + + + + + + + +
- int BoxAttr[HIGHT][WIDTH] = {
- 0 , 0 , 0 , 1 , 1 , 1 , 2 , 2 , 2 ,
- 0 , 0 , 0 , 1 , 1 , 1 , 2 , 2 , 2 ,
- 0 , 0 , 0 , 1 , 1 , 1 , 2 , 2 , 2 ,
- 3 , 3 , 3 , 4 , 4 , 4 , 5 , 5 , 5 ,
- 3 , 3 , 3 , 4 , 4 , 4 , 5 , 5 , 5 ,
- 3 , 3 , 3 , 4 , 4 , 4 , 5 , 5 , 5 ,
- 6 , 6 , 6 , 7 , 7 , 7 , 8 , 8 , 8 ,
- 6 , 6 , 6 , 7 , 7 , 7 , 8 , 8 , 8 ,
- 6 , 6 , 6 , 7 , 7 , 7 , 8 , 8 , 8
- };
- ==============================
- */