37. Sudoku Solver

Write a program to solve a Sudoku puzzle by filling the empty cells.

Empty cells are indicated by the character '.'.

You may assume that there will be only one unique solution.


A sudoku puzzle...


...and its solution numbers marked in red.


这道题就是做数独。。直接用深度搜索。用三个9*10的二维数组记录每一行,每一列和每一个九宫格已经有的数,然后就可以开始深度搜索,在‘.’处填进适合的数,最后只要得到答案就立刻停止,答案就存在board里。


我的代码(4ms):

class Solution {
public:
bool flg=false;
bool rows[9][10],cols[9][10],squares[9][10];

void dfs(vector<vector<char> >&board,int i,int j)
{
	if(flg) return;
	if(i>=9) 
	{
		flg=true;
		return;
	}
	int i1=i+(j+1)/9,j1=(j+1)%9;
	if(board[i][j]=='.')
	{
		for(int k=1;k<=9;k++)
		{
			if((!rows[i][k])&&(!cols[j][k])&&(!squares[(i/3)*3+j/3][k]))
			{
				board[i][j]=k+'0';
				rows[i][k]=cols[j][k]=squares[(i/3)*3+j/3][k]=true;
	            dfs(board,i1,j1);
	            rows[i][k]=cols[j][k]=squares[(i/3)*3+j/3][k]=false;
	            if(flg) return;
			}
		}
		board[i][j]='.';
	}
	else dfs(board,i1,j1);
}

void solveSudoku(vector<vector<char> >& board)
{
	for(int i=0;i<9;i++)
	{
		for(int j=0;j<9;j++)
		{
			if(board[i][j]!='.') 
			{
				int num=board[i][j]-'0';
				rows[i][num]=cols[j][num]=squares[(i/3)*3+j/3][num]=true;
			}
		}
	}
	dfs(board,0,0);
}
};


讨论上有一个用位运算的做的。。0ms 

class Solution {
public:
bool solveSudoku(int *sequence, int begin, short *rows, short *cols, short *subs,
                 const int *row_index, const int *col_index, const int *sub_index)
{
    for (int s = begin; s < 81; ++s)
    {
        int i = row_index[s], j = col_index[s], k = sub_index[s];
        if (!sequence[s])
        {
            short candidates = ~rows[i] & ~cols[j] & ~subs[k];
            while (candidates & 0x1ff)
            {
                short val = candidates & (-candidates);
                sequence[s] = val;
                rows[i] |= val; cols[j] |= val; subs[k] |= val;
                if (solveSudoku(sequence, s + 1, rows, cols, subs, row_index, col_index, sub_index))
                    return true;
                sequence[s] = 0;
                rows[i] &= ~val; cols[j] &= ~val; subs[k] &= ~val;
                candidates &= ~val;
            }
            return false;
        }
    }
    return true;
}

void solveSudoku(vector<vector<char>> &board)
{
    short rows[9]{ 0 }, cols[9]{ 0 }, subs[9]{ 0 };
    int sequence[81]{ 0 }, row_index[81], col_index[81], sub_index[81];
    for (int i = 0; i < 9; ++i)
    {
        for (int j = 0; j < 9; ++j)
        {
            int s = 9 * i + j;
            row_index[s] = i; col_index[s] = j; sub_index[s] = (i / 3) * 3 + j / 3;
            if (board[i][j] != '.')
            {
                sequence[s] = 1 << (board[i][j] - '1');
                rows[i] |= sequence[s]; cols[j] |= sequence[s]; subs[sub_index[s]] |= sequence[s];
            }
        }
    }
    solveSudoku(sequence, 0, rows, cols, subs, row_index, col_index, sub_index);
    for (int i = 0; i < 9; ++i)
    {
        for (int j = 0; j < 9; ++j)
        {
            if (board[i][j] == '.')
            {
                int s = 9 * i + j, n;
                for (n = 0; sequence[s] != (1 << n); ++n)
                    ;
                board[i][j] = n + '1';
            }
        }
    }
}
};


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值