数独一般只有一个解,这里给出一个多解的数独测试程序。总共13个解。如其中一个解为:
|7 8 1 |6 4 5 |3 2 9
|9 2 5 |1 7 3 |4 6 8
|3 6 4 |9 2 8 |7 5 1
|8 7 9 |5 6 4 |2 1 3
|5 3 2 |7 8 1 |6 9 4
|1 4 6 |2 3 9 |8 7 5
|4 1 7 |8 9 2 |5 3 6
|2 9 3 |4 5 6 |1 8 7
|6 5 8 |3 1 7 |9 4 2
如果是标准数独,只有一个解,那么最好设置一个boolean变量,表示是否得到解,之后所有的回溯函数都直接return,减少时间
public class Sth {
int count = 0;
int[][] a;
int[][] rows;
int[][] cols;
int[][] boxes;
public void solve(String[] str) {
strToInt(str);
backTrack(0, 0);
System.out.println("解法有:" + count);
}
public boolean couldPlace(int i, int row, int col) {
int box = (row / 3) * 3 + col / 3;
return rows[row][i] + cols[col][i] + boxes[box][i] == 0;
}
public void backTrack(int row, int col) {
if (a[row][col] == 0) {
for (int i = 1; i <= 9; i++) {
if (couldPlace(i, row, col)) {
place(i, row, col);
if (row == 8 && col == 8) {
count++;
print(a);
} else if (col == 8)
backTrack(row + 1, 0);
else
backTrack(row, col + 1);
remove(i, row, col);
}
}
} else if (row == 8 && col == 8) {
count++;
print(a);
} else if (col == 8)
backTrack(row + 1, 0);
else
backTrack(row, col + 1);
}
private void print(int[][] a) {
for (int i = 0; i < 9; i++) {
if (i % 3 == 0)
System.out.println("");
for (int j = 0; j < 9; j++) {
if (j % 3 == 0)
System.out.print("|");
System.out.print(a[i][j] + " ");
}
System.out.println();
}
System.out.println("--------------------");
}
private void remove(int i, int row, int col) {
a[row][col] = 0;
rows[row][i] = 0;
cols[col][i] = 0;
boxes[(row / 3) * 3 + col / 3][i] = 0;
}
private void place(int i, int row, int col) {
a[row][col] = i;
rows[row][i] = 1;
cols[col][i] = 1;
boxes[(row / 3) * 3 + col / 3][i] = 1;
}
public void strToInt(String[] str) {
int m = str.length, n = str[0].length();
a = new int[m][n];
rows = new int[m][n + 1];
cols = new int[m][n + 1];
boxes = new int[m][n + 1];
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
int tmp = str[i].charAt(j) - 48;
if (tmp != 0) {
a[i][j] = tmp;
rows[i][tmp] = 1;
cols[j][tmp] = 1;
boxes[(i / 3) * 3 + j / 3][tmp] = 1;
}
}
}
}
public static void main(String[] args) {
Sth sth = new Sth();
String[] str = {
"000000009", "020100400", "004020700",
"800004210", "000701000", "046200005",
"007090500", "003006080", "600000000"
};
sth.solve(str);
}
}