dfs,主要问题还是如何标记已用过的数字。
做三个布尔类型数组vx(标记行用过的数字),vy(标记列用过的数字),vv(标记每一个小数独用过的数字)。
对于方格(x,y),对应小方格标号为 (x/3)*3+y/3.
代码如下:
public class L6 {
static boolean f = false;
static boolean[][] vx = new boolean[10][10];// 行的情况
static boolean[][] vy = new boolean[10][10];// 列的情况
static boolean[][] vv = new boolean[10][10];// 小格 3x3的情况
static void dfs(int x, int y, char[][] s) {
// System.out.println(x + " " + y);
if (f) {
return;
}
if (x == 9) {
f = true;
show(s);
return;
}
if (y == 9) {
dfs(x + 1, 0, s);
return;
}
if (s[x][y] != '*') {
dfs(x, y + 1, s);
return;
}
for (int i = 1; i <= 9; i++) {
if (!vx[x][i] && !vy[y][i] && !vv[x / 3 * 3 + y / 3][i]) {
s[x][y] = (char) ('0' + i);
vx[x][i] = true;
vy[y][i] = true;
vv[x / 3 * 3 + y / 3][i] = true;
dfs(x, y + 1, s);
vx[x][i] = false;
vy[y][i] = false;
vv[x / 3 * 3 + y / 3][i] = false;
s[x][y] = '*';
}
}
}
static void show(char[][] s) {
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
System.out.print(s[i][j]);
}
System.out.println();
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
char[][] s = new char[10][10];
s[0] = "*26******".toCharArray();
s[1] = "***5*2**4".toCharArray();
s[2] = "***1****7".toCharArray();
s[3] = "*3**2*18*".toCharArray();
s[4] = "***3*9***".toCharArray();
s[5] = "*54*1**7*".toCharArray();
s[6] = "5****1***".toCharArray();
s[7] = "6**9*7***".toCharArray();
s[8] = "******75*".toCharArray();
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
if (s[i][j] != '*') {
vx[i][s[i][j] - '0'] = true;
vy[j][s[i][j] - '0'] = true;
vv[i / 3 * 3 + j / 3][s[i][j] - '0'] = true;
}
}
}
System.out.println(s.length + " " + s[0].length);
dfs(0, 0, s);
}
}