编写一个程序,通过已填充的空格来解决数独问题。
一个数独的解法需遵循如下规则:
- 数字
1-9
在每一行只能出现一次。 - 数字
1-9
在每一列只能出现一次。 - 数字
1-9
在每一个以粗实线分隔的3x3
宫内只能出现一次。
空白格用 '.'
表示。
一个数独。
答案被标成红色。
Note:
- 给定的数独序列只包含数字
1-9
和字符'.'
。 - 你可以假设给定的数独只有唯一解。
- 给定数独永远是
9x9
形式的。
class Solution {
public:
//回溯
struct Pos{
int x,y;
Pos(int x, int y){this->x = x; this->y = y;}
};
bool is_val(vector<vector<char> > &board, int x, int y, char val){
for(int j=0;j<9;++j){
if(j==y)
continue;
if(board[x][j] == val)
return false;
}
for(int i=0;i<9;++i){
if(i==x)
continue;
if(board[i][y] == val)
return false;
}
int s_i = x/3*3, s_j = y/3*3;
for(int i=s_i; i<s_i+3; ++i)
for(int j=s_j; j<s_j+3; ++j){
if(i==x && j==y)
continue;
if(board[i][j] == val)
return false;
}
return true;
}
void test_print(vector<vector<char>> &board){
for(int i=0;i<9;i++){
for(int j=0;j<9;j++){
cout<<board[i][j]<<" ";
}
cout<<endl;
}
}
bool end = false;
void back_trace(vector<vector<char>> &board, vector<Pos> &vec, int index){
if(end || index == vec.size()){
end = true;
return;
}
int x = vec[index].x, y = vec[index].y;
for(int i=1;i<10;++i){
if(is_val(board, x, y, i+'0')){
if(end)
return;
board[x][y] = i+'0';
back_trace(board, vec, index+1);
if(end)
return;
board[x][y] = '.';
}
}
}
void solveSudoku(vector<vector<char>>& board) {
vector<Pos> vec;
for(int i=0;i<9;++i)
for(int j=0;j<9;++j)
if(board[i][j] == '.')
vec.push_back(Pos(i,j));
back_trace(board, vec, 0);
}
};