Sudoku Solver leetcode

用位运算优化了一下,需要填入的点也事先扫描出来,每个格子属于哪个九宫格也事先算出。

class Solution {
    struct point
    {
        int x,y;
        point(int X=0,int Y=0):x(X),y(Y){}
    }next_point[9][9];
    vector<vector<char>> *pData;
    static const int mask=0x000001FF;
    char log2ADD1[513];
    int hash[9][9];
    int row_forbid[9],col_forbid[9],cur_forbid[9];
    bool dfs(int toFill,int x,int y)
    {
        int nextx=next_point[x][y].x,nexty=next_point[x][y].y;
        int cur=hash[x][y];
        int not_forbid=mask&~(row_forbid[x]|col_forbid[y]|cur_forbid[cur]);
        while (not_forbid>0)
        {
            int p=not_forbid&(-not_forbid);
            not_forbid^=p;
            (*pData)[x][y]=log2ADD1[p];
            row_forbid[x]|=p;
            col_forbid[y]|=p;
            cur_forbid[cur]|=p;
            if (toFill==1 || dfs(toFill-1,nextx,nexty))    
                return true;
            row_forbid[x]^=p;
            col_forbid[y]^=p;
            cur_forbid[cur]^=p;
        }
        return false;
    }
public:
    void solveSudoku(vector<vector<char> > &board) {
        int i,j,toFill=0;
        for (i=j=1;i<=9;++i)
        {
            log2ADD1[j]=i+'0';
            j<<=1;
        }
        for (i=0;i<9;++i)
            for (j=0;j<9;++j)
                hash[i][j]=i/3*3+j/3;
        pData=&board;
        memset(row_forbid,0,sizeof(row_forbid));
        memset(col_forbid,0,sizeof(col_forbid));
        memset(cur_forbid,0,sizeof(cur_forbid));
        point pre;
        for (i=0;i<9;++i)
        {
            for (j=0;j<9;++j)
            {
                if (board[i][j]!='.')
                {
                    int forbid=1<<(board[i][j]-'1');
                    row_forbid[i]|=forbid;
                    col_forbid[j]|=forbid;
                    cur_forbid[hash[i][j]]|=forbid;
                }
                else
                {
                    ++toFill;
                    if (toFill>1)
                    {
                        next_point[pre.x][pre.y].x=i;
                        next_point[pre.x][pre.y].y=j;
                    }
                    pre.x=i;
                    pre.y=j;
                }
            }
        }
        for (i=0;i<9;++i)
            for (j=0;j<9;++j)
                if (board[i][j]=='.')
                {
                    dfs(toFill,i,j);
                    return;
                }
    }
};
View Code

 

posted on 2014-03-13 20:04  Deller  阅读(130)  评论(0)    收藏  举报

导航