题目:
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宫格分成81个空,如果是数字,则访问下一个空,如果是‘.’,则填入1-9的数字,然后检查行、列以及小单元格是否满足,如果满足,则暂时写入,并访问下一个空格。如果发现后面的某一个空格所有数字都不满足,说明前面有数字虽然对该数字所处的行列及小单元格满足,但是会造成无解,也不符合要求,于是回溯到该空格,重新填入下一个数字,以此下去。
class Solution1
{
public:
void solveSudoku(vector<vector<char>>&board)
{
solve(board,0);
}
bool solve(vector<vector<char>>&board,int index)
{
if(index==81) return true;
int i=index/9,j=index%9; //行和列
if(board[i][j]!='.') return solve(board,index+1); //如果是数字就不用处理
else
{
for(char f='1';f<='9';f++)
if(isValidFill(board,i,j,f))
{
board[i][j]=f;
if(solve(board,index+1)) return true; //非常重要,回溯关键,如果不满足,则测试f下一个值
board[i][j]='.'; //非常重要,回溯关键
}
return false; //如果后面有的'.'所有数字测试完了都不满足,说明前面有的数字不合格
}
}
bool isValidFill(vector<vector<char>>&board,int i,int j,char fill)
{
for(int k=0;k<9;k++)
{
if(board[i][k]==fill) return false; //检查行
if(board[k][j]==fill) return false; //检查列
int r=i/3*3+j/3; //求出是第几块
if(board[r/3*3+k/3][r%3*3+k%3]==fill) return false; //检查块
}
return true;
}
};