题意:完成数独程序,数独要求每行每列且每个3*3矩阵都必须是1~9的数字组成。
思路:dfs
- 用row[i][n] 记录第i行n存在 用col[j][n] 记录第j列n存在 grid[k][n] 记录第k个3*3中的n存在
- 遍历的时候,先把列遍历完然后在遍历行
if (map[r][c]) { if (c == 8) flag = dfs(r + 1, 0); else flag = dfs(r, c + 1); return flag; }
现在推
第一个矩阵为 0,0 0,1 0,2 第二个矩阵为 0,3 0,4 0,5
1,0 1,1 1,2 1,3 1,4 1,5
2,0 2,1 2,2 2,3 2,4 2,5
如果直接 (r+c)/3有些不符合,说明应该把 r c拆开来看 所以推出 r/3*3+c/3
解决问题的代码:
#include<cstdio> #include<cstring> using namespace std; const int maxn = 10; int map[maxn][maxn]; bool row[maxn][maxn]; bool col[maxn][maxn]; bool grid[maxn][maxn]; bool dfs(int r, int c) { if (r == 9) return true;//构造完毕 bool flag = false; if (map[r][c]) { if (c == 8) flag = dfs(r + 1, 0); else flag = dfs(r, c + 1); return flag; } int k = (r / 3) * 3 + c / 3; for (int i = 1; i <= 9; i++)if (!row[r][i] && !col[c][i] && !grid[k][i]) { row[r][i] = col[c][i] = grid[k][i] = true; map[r][c] = i; if (c == 8) flag = dfs(r + 1, 0); else flag = dfs(r, c + 1); if (flag) return true; map[r][c] = 0; row[r][i] = col[c][i] = grid[k][i] = false; } return false; } int main() { int T; scanf("%d", &T); while (T--) { memset(row, 0, sizeof(row)); memset(col, 0, sizeof(col)); memset(grid, 0, sizeof(grid)); for (int i = 0; i<9; i++) for (int j = 0; j<9; j++) { char x; scanf(" %c", &x); map[i][j] = x - '0'; if (map[i][j]) { row[i][map[i][j]] = true; col[j][map[i][j]] = true; int k = (i / 3) * 3 + j / 3; grid[k][map[i][j]] = true; } } dfs(0, 0); for (int i = 0; i<9; i++) { for (int j = 0; j<9; j++) printf("%d", map[i][j]); printf(" "); } } return 0; }