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("
");
    }
}

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 ;
    		}
    	}
    }
}
原文地址:https://www.cnblogs.com/Emerald/p/4321758.html