数独题,经典的回溯法求解,思路比较简单
遍历整个数组,如果是数字,就跳过,访问下一个,如果是?,就用数字1-9去试探,当整张表都遍历完了,结果就出来了。
我设置了一个res变量来统计解的情况,如果res = 1了,就代表找到一组解了然后就直接return了。如果是无解的情况的话,那么res=0;
要注意的一点就是关于判断是否可以放的方法
我这里用的是三个布尔型的数组
boolean[][] rowUsed = new boolean[9][10];
boolean[][] colUsed = new boolean[9][10];
boolean[][][] boxUsed = new boolean[3][3][10];
rowUsed 和 colUsed比较简单,boxUsed的判断方法如下:
将数独的棋盘分为9个九宫格, boxUsed[row/3][col/3][num],
例如:当row = 2, col = 2 的时候,就代表的是第一个九宫格,以此类推
不要将下面的代码拿到HDU去提交,因为会wa,我也不知道为什么
package 搜索.一般.回溯.HDU1426_数独;
import java.util.Scanner;
public class Main {
static int res = 0;
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int count = 0;
char[][] board = new char[9][9];
while(sc.hasNext()) {
for (int i = 0; i < 9; i++) {
String t = sc.nextLine();
t = t.replaceAll(" ","");
//System.out.println(t);
board[i] = t.toCharArray();
}
// 三个布尔数组 表明 行, 列, 还有 3*3 的方格的数字是否被使用过
boolean[][] rowUsed = new boolean[9][10];
boolean[][] colUsed = new boolean[9][10];
boolean[][][] boxUsed = new boolean[3][3][10];
// 初始化
for(int row = 0; row < board.length; row++){
for(int col = 0; col < board[0].length; col++) {
int num = board[row][col] - '0';
if(1 <= num && num <= 9){
rowUsed[row][num] = true;
colUsed[col][num] = true;
boxUsed[row/3][col/3][num] = true;
}
}
}
if(count++ > 0) System.out.println();
// 递归尝试填充数组
dfs(board,rowUsed,colUsed,boxUsed,0,0);
res = 0;
}
}
public static void dfs(char[][]board, boolean[][]rowUsed, boolean[][]colUsed, boolean[][][]boxUsed, int row, int col) {
if (res == 1) return;
// 边界校验, 如果已经填充完成, 返回true, 表示一切结束
if(col == board[0].length){
col = 0;
row++;
if(row == board.length){
res++;
show(board);
return;
}
}
// 是空则尝试填充, 否则跳过继续尝试填充下一个位置
if(board[row][col] == '?') {
// 尝试填充1~9
for(int num = 1; num <= 9; num++){
boolean canUsed = !(rowUsed[row][num] || colUsed[col][num] || boxUsed[row/3][col/3][num]);
if(canUsed){
//试探
rowUsed[row][num] = true;
colUsed[col][num] = true;
boxUsed[row/3][col/3][num] = true;
board[row][col] = (char)('0' + num);
dfs(board, rowUsed, colUsed, boxUsed, row, col + 1);
//回溯
board[row][col] = '?';
rowUsed[row][num] = false;
colUsed[col][num] = false;
boxUsed[row/3][col/3][num] = false;
}
}
} else {
dfs(board, rowUsed, colUsed, boxUsed, row, col + 1);
}
}
public static void show(char[][] board) {
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
System.out.print(board[i][j]);
if (j != 8) {
System.out.print(" ");
}
}
System.out.println();
}
}
}