您的位置:首页 > 其它

数独破解(回溯,暴力dfs+剪枝)

2017-04-22 00:04 435 查看
问题描述:对于一个给定的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
*/
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: