这题也是经典回溯题,跟八皇后很像。
注意:
1) 还是用位运算最方便。
2) dfs参数用一个index就可以了,然后转换成row和col。
3) 如果当前格不是'.',那就跳过去处理下一格。
#include <iostream>
#include <vector>
using namespace std;
vector<int> row(9,0), col(9,0), grids(9,0);
void preprocess(vector<vector<char>>& board) {
if (board.size()!=9) return;
for (int i=0; i<9; ++i) {
if (board[i].size()!=9) return;
for (int j=0; j<9; ++j) {
char c=board[i][j];
if (c!='.') {
int k=0x1<<(board[i][j]-'0');
row[i]|=k; col[j]|=k; grids[i/3*3+j/3]|=k;
}
}
}
}
bool dfs(int index, vector<vector<char>>& board) {
if (index==81)
return true;
int r=index/9, c=index%9;
if (board[r][c]=='.') {
for (int i=1; i<=9; i++) { //note: not i=0..8
int j=0x1<<i;
if (!(row[r]&j) && !(col[c]&j) && !(grids[r/3*3+c/3]&j)) {
row[r]|=j; col[c]|=j; grids[r/3*3+c/3]|=j;
board[r][c]='0'+i;
if (dfs(index+1, board)) {
return true;
}
row[r]^=j; col[c]^=j; grids[r/3*3+c/3]^=j;
board[r][c]='.';
// return false; //do not return as we can still try other i !!!
}
}
return false;
}else { //if current board unit is number, then continue with dfs on next unit
return dfs(index+1, board);
}
}
void solveSudoku(vector<vector<char>>& board) {
preprocess(board);
dfs(0, board);
}
int main()
{
vector<vector<char> > board{{'5','3','.','.','7','.','.','.','.'},
{'6','.','.','1','9','5','.','.','.'},
{'.','9','8','.','.','.','.','6','.'},
{'8','.','.','.','6','.','.','.','3'},
{'4','.','.','8','.','3','.','.','1'},
{'7','.','.','.','2','.','.','.','6'},
{'.','6','.','.','.','.','2','8','.'},
{'.','.','.','4','1','9','.','.','5'},
{'.','.','.','.','8','.','.','7','9'}};
solveSudoku(board);
for (auto i=0; i<9; i++) {
for (auto j=0; j<9; j++)
cout<<board[i][j]<<" ";
cout<<endl;
}
return 0;
}