1.题目
2.求解
本题,一眼看过去想法,想尝试用动态规划求解,但是好像不太行,但是可以使用状压的一点点思想,也就是用二进制来保存当前状态,然后用搜索即可,因为数独只是一个9 * 9的数组,搜索范围不大,使用dfs找到唯一解直接退出所有搜索即可。
3.代码
int a[10], b[10], c[10];
bool flag;
int cnt;
struct node{
int x;
int y;
int r;
int remain;
};
node ma[85];
bool cmp(node a, node b){
return a.remain < b.remain;
}
class Solution {
public:
static void dfs(int idx, vector<vector<char>>& board){
if(idx == cnt) {
flag = true;
return ;
}
int num = a[ma[idx].x] | b[ma[idx].y] | c[ma[idx].r];
for(int i = 0; i < 9; i++){
if(!((1 << i) & num)) {
a[ma[idx].x] += (1 << i);
b[ma[idx].y] += (1 << i);
c[ma[idx].r] += (1 << i);
board[ma[idx].x][ma[idx].y] = char(i + '1');
dfs(idx + 1, board);
if (flag) return;
a[ma[idx].x] -= (1 << i);
b[ma[idx].y] -= (1 << i);
c[ma[idx].r] -= (1 << i);
}
}
}
void solveSudoku(vector<vector<char>>& board) {
int i, j;
memset(a, 0, sizeof(a));
memset(b, 0, sizeof(b));
memset(c, 0, sizeof(c));
flag = false;
cnt = 0;
for(i = 0; i < 9; i++){
for(j = 0; j < 9; j++){
if(board[i][j] != '.'){
a[i] += (1 << (board[i][j] - '1'));
b[j] += (1 << (board[i][j] - '1'));
c[(i / 3 * 3) + j / 3] += (1 << (board[i][j] - '1'));
}
}
}
for(i = 0; i < 9; i++){
for(j = 0; j < 9; j++){
if(board[i][j] == '.'){
ma[cnt].x = i;
ma[cnt].y = j;
ma[cnt].r = (i / 3 * 3) + j / 3;
ma[cnt++].remain = 9 - __builtin_popcount(a[i] | b[j] | c[(i / 3 * 3) + j / 3]);
}
}
}
sort(ma, ma + cnt, cmp);
dfs(0, board);
}
};