数独问题
每行每列每个九宫格没有相同的数。
思路
从左上角开始试数,如果这条解答树支路不行就剪枝。直到遍历完整棵解答树。
细节
1.通过行列的数值推算所在九宫格的编号
直接记住公式行了:f(r, c) = 3*((r-1)/3) + ((c-1)/3) + 1
2. 如果这条支路不行别忘了撤销这一步,恢复起始状态。
代码
#include <cstdio>
#include <cstring>
char m[15][15];
bool visr[15][15];
bool visc[15][15];
bool visn[15][15];
int f(int r, int c) {
return 3*((r-1)/3)+((c-1)/3)+1;
}
bool dfs(int r, int c) {
int k = f(r, c);
if (r == 10) return true;
bool flag = false;
if (m[r][c] != '0') {
if (c == 9) {
flag = dfs(r+1, 1);
}
else {
flag = dfs(r, c+1);
}
return flag;
}
else {
for(int i = 1; i <= 9; i++) {
if (!visc[c][i] && !visr[r][i] && !visn[k][i]) {
visc[c][i] = true;
visn[k][i] = true;
visr[r][i] = true;
m[r][c] = i +'0';
if (c == 9) {
flag = dfs(r+1, 1);
}
else {
flag = dfs(r, c+1);
}
if (!flag) { // 如果这条路不行,撤销~
m[r][c] = '0';
visc[c][i] = false;
visr[r][i] = false;
visn[k][i] = false;
}
else
return true;
}
}
}
return false;
}
int main()
{
//freopen("input.txt", "r", stdin);
int T;
scanf("%d", &T);
getchar();
while(T--) {
memset(visc, false, sizeof(visc));
memset(visr, false, sizeof(visr));
memset(visn, false, sizeof(visn));
for(int i = 1; i <= 9; i++) {
for(int j = 1; j <= 9; j++) {
m[i][j] = getchar();
int k = f(i, j);
if (m[i][j] != '0') {
int t = m[i][j] - '0';
visr[i][t] = true;
visc[j][t] = true;
visn[k][t] = true;
}
}
m[i][10] = '\0';
getchar();
}
dfs(1, 1);
for(int i = 1; i <= 9; i++) {
printf("%s\n", m[i]+1);
}
}
return 0;
}
细节决定成败~