zoukankan      html  css  js  c++  java
  • 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 ;
        		}
        	}
        }
    }
    
  • 相关阅读:
    b_jd_水坑数量(向外流dfs)
    b_wy_购买商品使得满减最省(01背包)
    b_wy_最优路径(构造树+dfs)
    Redis:List列表相关指令
    Redis:String字符串常用指令
    Redis:linux基本的指令
    Redis:redis-benchmark性能测试/压力测试
    Redis:增大并发量的演进过程
    Kafka的下载安装和测试,及消费端数据中文乱码问题
    Git:常用命令
  • 原文地址:https://www.cnblogs.com/Emerald/p/4321758.html
Copyright © 2011-2022 走看看