Sudoku
https://vjudge.net/problem/HRBUST-1955
9 * 9 的 Sudoku 给每个格子标号 num 并且通过标号唯一确定格子的位置在 num / 9 行 num % 9 列
判断待定数字是不是在每行每列每宫中没有出现过 如果可以顺利搜索完所有格子 ans 标为 1 如果搜索完 ans 不是 1 那么无解
#include <cstdio> #include <iostream> #include <cstring> using namespace std; const int maxn = 12; int T; char s[maxn][maxn]; int a[maxn][maxn]; int r[maxn][maxn], c[maxn][maxn], g[maxn][maxn]; int G[maxn][maxn]; int ans; void init() { ans = 0; memset(r, 0, sizeof r); memset(c, 0, sizeof c); memset(g, 0, sizeof g); } // 求第几宫 int u(int x, int y) { x = x / 3; y = y / 3; return 3 * x + y; } void dfs(int num) { if(num == 81) { ans = 1; return; } int x = num / 9, y = num % 9; if(a[x][y] != 0) { dfs(num + 1); if(ans == 1) return; } else { for(int i = 1; i <= 9; i ++) { if(r[x][i] || c[y][i] || g[G[x][y]][i]) continue; a[x][y] = i; r[x][i] = 1; c[y][i] = 1; g[G[x][y]][i] = 1; dfs(num + 1); if(ans == 1) return; a[x][y] = 0; r[x][i] = 0; c[y][i] = 0; g[G[x][y]][i] = 0; } } } int main() { scanf("%d", &T); for(int cas = 1; cas <= T; cas ++) { init(); for(int i = 0; i < 9; i ++) { scanf("%s", s[i]); for(int j = 0; s[i][j]; j ++) { G[i][j] = u(i, j); if(s[i][j] == '*') s[i][j] = '0'; a[i][j] = s[i][j] - '0'; if(a[i][j] != 0) { r[i][a[i][j]] = 1; // 第 i 行已经出现了 a[i][j] c[j][a[i][j]] = 1; // 第 j 列已经出现了 a[i][j] g[G[i][j]][a[i][j]] = 1; // 第 G(i, j) 宫已经出现了 a[i][j] } } } dfs(0); if(ans == 1) { for(int i = 0; i < 9; i ++) { for(int j = 0; j < 9; j ++) { printf("%d", a[i][j]); } printf("\n"); } printf("\n"); } else { printf("No solution\n"); } } return 0; }