數獨破解(回溯,暴力dfs+剪枝)
阿新 • • 發佈:2019-01-29
問題描述:對於一個給定的9*9方格里,填了若干數字,且滿足以下條件:
① 每個橫行和豎列中的9個格子都包含數字1~9,且不重複;
② 每個黑色粗實線圍住的9個格子(3×3)都包含數字1~9,且不重複
思路:從左上角開始,通過對每一個沒有填數的格子進行1到9的遍歷,然後通過約束函式來判斷該該格子的填數是否符合規則,若符合就遞進到下一個(即右邊的格子),假若下一個格子已超出右邊界,則遞進到下一行的第0個格子處,依此類推,直到超出下邊界,即完成其中一種數獨填數!
import java.util.Scanner;
public class Main {
static int count = 0 ;// 記錄該數獨的解法個數
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int[][] map = new int[9][9];
for (int i = 0; i < 9; i++)
for (int j = 0; j < 9; j++)
map[i][j] = in.nextInt();
f(map, 0, 0);
}
public static void f(int[][] map, int x, int y) {
if (x > 8) {
System.out.println("第" + ++count + "種解法:");
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++)
System.out.print(map[i][j] + " ");
System.out.println();
}
return ;
}
if (y > 8) {
f(map, x + 1, 0);
return;
}
// 0表示沒有填數
if (map[x][y] == 0) {
for (int k = 1; k <= 9; k++) {
map[x][y] = k;
if (OK(map, x, y))
f(map, x, y + 1);
}
map[x][y] = 0;
} else
f(map, x, y + 1);
}
private static boolean OK(int[][] map, int x, int y) {
// 判斷列
for (int i = 0; i < 9; i++)
if (map[i][y] == map[x][y] && i != x)
return false;
// 判斷行
for (int i = 0; i < 9; i++)
if (map[x][i] == map[x][y] && i != y)
return false;
// 判斷九宮格,找到當前判斷格子 所屬的九宮格
int leftx = x / 3 * 3;// lextx為目前所在的九宮格的起始x座標,即九宮格左上角的x座標
int lefty = y / 3 * 3;// lexty為目前所在的九宮格的起始y座標
int endx = leftx + 2;// endx為目前所在的九宮格的末尾x座標,即九宮格右下角的x座標
int endy = lefty + 2;// endx為目前所在的九宮格的末尾x座標,即九宮格右下角的y座標
for (int i = leftx; i <= endx; i++)
for (int j = lefty; j <= endy; j++) {
if (i == x && j == y)
continue;
if (map[i][j] == map[x][y])
return false;
}
// 通過檢測
return true;
}
}
/*
Input:
0 6 1 0 3 0 0 2 0
0 5 0 0 0 8 1 0 7
0 0 0 0 0 7 0 3 4
0 0 9 0 0 6 0 7 8
0 0 3 2 0 9 5 0 0
5 7 0 3 0 0 9 0 0
1 9 0 7 0 0 0 0 0
8 0 2 4 0 0 0 6 0
0 0 0 0 0 0 0 0 0
Output:
第1種解法:
7 6 1 9 3 4 8 2 5
3 5 4 6 2 8 1 9 7
9 2 8 1 5 7 6 3 4
2 1 9 5 4 6 3 7 8
4 8 3 2 7 9 5 1 6
5 7 6 3 8 1 9 4 2
1 9 5 7 6 2 4 8 3
8 3 2 4 1 5 7 6 9
6 4 7 8 9 3 2 5 1
第2種解法:
7 6 1 9 3 4 8 2 5
3 5 4 6 2 8 1 9 7
9 2 8 1 5 7 6 3 4
2 1 9 5 4 6 3 7 8
4 8 3 2 7 9 5 1 6
5 7 6 3 8 1 9 4 2
1 9 5 7 6 2 4 8 3
8 3 2 4 9 5 7 6 1
6 4 7 8 1 3 2 5 9
*/
}