1. 程式人生 > >數獨破解(回溯,暴力dfs+剪枝)

數獨破解(回溯,暴力dfs+剪枝)

問題描述:對於一個給定的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 */ }