POJ-2676 Sudoku 搜索
题意:给定一个数独的题目,0代表这个点的值未确定,现在要求填写数字进去且满足:
1.每一行必须是1-9的集合
2.每一列必须是1-9的集合
3.每一个子矩阵内必须是1-9的集合
由于给定的约束条件比较多,因此直接dfs即可。
代码如下:
#include <cstdlib> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; char G[15][15]; int r[15][15], c[15][15], f[15][15]; // G用来保留整个图,R用来说明某一行有了哪些数字 // C用来说明某一列有了哪些数 bool finish; int getzone(int x, int y) { int a = (x - 1) / 3; int b = (y - 1) / 3; return a * 3 + b; } void dfs(int x, int y) { if (x == 9 && y == 9) { finish = true; return; } int lim; for (int i = x; i <= 9; ++i) { lim = i == x ? y + 1 : 1; for (int j = lim; j <= 9; ++j) { if (G[i][j] == 0) { for (int k = 1; k <= 9; ++k) { if (!r[i][k] && !c[j][k] && !f[getzone(i, j)][k]) { r[i][k] = c[j][k] = f[getzone(i, j)][k] = 1, G[i][j] = k; dfs(i, j); if (finish) break; else { r[i][k] = c[j][k] = G[i][j] = f[getzone(i, j)][k] = 0; } } } goto loop; } else if (i == 9 && j == 9) { finish = true; } } } loop: return; } int main() { int T; scanf("%d", &T); while (T--) { finish = false; memset(r, 0, sizeof (r)); memset(c, 0, sizeof (c)); memset(f, 0, sizeof (f)); for (int i = 1; i <= 9; ++i) { scanf("%s", G[i]+1); for (int j = 1; j <= 9; ++j) { G[i][j] -= '0'; f[getzone(i, j)][G[i][j]] = 1; r[i][G[i][j]] = 1; c[j][G[i][j]] = 1; } } dfs(1, 0); // 递归这个点,下一个点直接进入(1, 1) for (int i = 1; i <= 9; ++i) { for (int j = 1; j <= 9; ++j) { printf("%d", G[i][j]); } puts(""); } } return 0; }