Hdu 1426 Sudoku Killer

Problem地址:http://acm.hdu.edu.cn/showproblem.php?pid=1426

 

一道可以用Dfs解决的题目。思路并不难,只要一个一个数字试就行了。

但很奇怪,我试图每次挑最可能的数字进行搜索,结果错了。后来直接搜索,没有考虑最有可能的数字,反而还对了。

估计我功力还不够深厚。

 

代码反复修改,虽然能AC,但代码的可读性有点降低。

#include <iostream>

#include <cstring>

#include <cstdio>



using namespace std;



const int MAXN = 9+3;

const int LENGTH = 9;

const int COUNTPOS = 12;

// the first param means it's in the ith row or column or rec, the second param means the exact num

int visRow[ MAXN ][ MAXN ]; // the row nums

int visCol[ MAXN ][ MAXN ]; // the colomn nums

int visRec[ MAXN ][ MAXN ][ MAXN ]; // the rectangle nums



const int EXIST = 1;

const int NOTEXSIT = 0;

const int UNKNOW = -1;

int sudoku[MAXN][MAXN];

int counter = 0;



inline int CharToInt( int c ) {

    if( c=='?' ) {

        return UNKNOW;

    } else {

        return c-'0';

    }

}



void PrintSudoKu( ) {

    int i, j;

    for( i=0; i<9; i++ ) {

        printf( "%d", sudoku[i][0] );

        for( j=1; j<9; j++ ) {

            printf( " %d", sudoku[i][j] );

        }

        printf("\n");

    }

}



void MakeVis() {

    memset( visCol, NOTEXSIT, sizeof(visCol) );

    memset( visRow, NOTEXSIT, sizeof(visRow) );

    memset( visRec, NOTEXSIT, sizeof(visRec) );

    int i, j;

    for( i=0; i<LENGTH; i++ ) {

        for( j=0; j<LENGTH; j++ ) {

            if( sudoku[i][j] != UNKNOW ) {

                visRow[i][ sudoku[i][j] ] = EXIST;

                visRow[i][ COUNTPOS ] ++;

                visCol[j][ sudoku[i][j] ] = EXIST;

                visCol[j][ COUNTPOS ] ++;

                visRec[ i/3 ][ j/3 ][ sudoku[i][j] ] = EXIST;

                visRec[ i/3 ][ j/3 ][ COUNTPOS ] ++;

                counter ++;

            }

        }

    }

}



void GetPos( int *x, int *y );

void Dfs( int x, int y );



int main()

{

    char c;

    int konghang = 0;

    while( cin >> c ) {

        sudoku[0][0] = CharToInt(c);

        if( konghang != 0 ) {

        	cout << endl;

        }

        konghang = 1;



        int i, j;

        for( i=1; i<9; i++ ) {

            cin >> c;

            sudoku[0][i] = CharToInt( c );

        }



        for( i=1; i<9; i++ ) {

            //getchar();

            cin >> c;

            sudoku[i][0] = CharToInt( c );

            for( j=1; j<9; j++ ) {

                cin >> c;

                sudoku[i][j] = CharToInt( c );

            }

        }



        counter = 0;

        MakeVis();

        int x ,y;

        GetPos( &x, &y );

        Dfs( x, y );

        PrintSudoKu();

    }

    return 0;

}



void GetPos( int *x, int *y ) {

    /*int i, temp = -1;

    for( i=0; i<LENGTH; i++ ) {

        if( temp<visRow[i][COUNTPOS] && visRow[i][COUNTPOS]!=LENGTH ) {

            temp = visRow[i][COUNTPOS];

            *x = i;

        }

    }

    for( i=*x; i<LENGTH; i++ ) {

        if( sudoku[*x][i]==UNKNOW ) {

            *y = i;

            return ;

        }

    }*/

     for( int i=0; i<9;i++ ) {

    	for( int j=0; j<9; j++ ) {

    		if( sudoku[i][j]==UNKNOW ) {

    			*x = i;

    			*y = j;

    			return ;

    		}

    	}

    }

}



void GetDfsPos( int x, int y, int *tempx, int *tempy );



void Dfs( int x, int y ) {

    if( counter == LENGTH*LENGTH ) {

        return ;

    }

    int vis[10] = {0};

    // which num isn't used

    int i;

    for( i=1; i<=9; i++ ) {

        if( visCol[y][i]!=NOTEXSIT )  vis[ i ] ++;

        if( visRow[x][i]!=NOTEXSIT ) vis[ i ] ++;

        if( visRec[x/3][y/3][i]!=NOTEXSIT ) vis[ i ] ++;

    }

    for( i=1; i<=9; i++ ) {

        if( vis[ i ]==0 ) {

            sudoku[x][y] = i;

            visCol[y][i] = EXIST; visRow[x][i] = EXIST; visRec[x/3][y/3][i] = EXIST;

            //visCol[y][COUNTPOS] ++; visRow[x][COUNTPOS] ++; visRec[x/3][y/3][COUNTPOS] ++;

            counter ++;



            int tempx, tempy;

            GetDfsPos( x, y, &tempx, &tempy );

            Dfs( tempx, tempy );



            if( counter == 81 ) {

                return ;

            }

            counter --;

            visCol[y][i] = NOTEXSIT; visRow[x][i] = NOTEXSIT; visRec[x/3][y/3][i] = NOTEXSIT;

            //visCol[y][COUNTPOS] --; visRow[x][COUNTPOS] --; visRec[x/3][y/3][COUNTPOS] --;

            sudoku[x][y] = UNKNOW;

        }

    }

}



void GetDfsPos( int x, int y, int *tempx, int *tempy ) {

    /*int tempCol = visCol[y][COUNTPOS]==9 ? -1 : visCol[y][COUNTPOS],

        tempRow = visRow[x][COUNTPOS]==9 ? -1 : visRow[x][COUNTPOS],

        tempRec = visRec[x/3][y/3][COUNTPOS]==9 ? -1 : visRec[x/3][y/3][COUNTPOS];

    if( tempCol>=tempRow && tempCol>=tempRec ) {

        for( int i=0; i<9; i++ ) {

            if( sudoku[i][y]==UNKNOW ) {

                *tempx = i; *tempy = y; return ;

            }

        }

    }

    if( tempRow>=tempCol && tempRow>=tempRec ) {

        for( int i=0; i<9; i++ ) {

            if( sudoku[x][i]==UNKNOW ) {

                *tempx = x; *tempy = i; return ;

            }

        }

    }

    for( int i= (x/3)*3; i<=(x/3)*3+2; i++ ) {

        for( int j= (y/3)*3; j<=(y/3)*3+2; j++ ) {

            if( sudoku[i][j]==UNKNOW ) {

                *tempx = i; *tempy = j; return ;

            }

        }

    }*/

    for( int i=0; i<9;i++ ) {

    	for( int j=0; j<9; j++ ) {

    		if( sudoku[i][j]==UNKNOW ) {

    			*tempx = i;

    			*tempy = j;

    			return ;

    		}

    	}

    }

}

 

你可能感兴趣的:(sudo)