一门语言不用算法解数独 , 最大的缺点就是方法冗余 , 且当题目有多个解时 , 不好都求出来 , 需要更多的取值试探
这里只是采取了我人为去玩数独时的一些经验 , 用这些经验去加快了数独的运算 , 这样的代码 , 我不知道算不算好代码
这里一共分三步
第一步: 从1~9按照最简单的规则每行每列每个九宫格去筛选填数
第二步: 标注出每个剩余空格的可填入的值 , 进行排除 . 比如一行里面有12,12 , 那么这一行除了这两个格子之外都不允许为12 , 若一行里面有123 123 12 , 那么这一行这三个格子只能填入123 . 那么每列每个九宫格都是同样的道理
第三部就是穷举了 , 选一个只有两个允许值的空格 , 假如第一行第一例的格子只能填入1和2 , 那么我们填入1 , 然后循环第二步 , 出现错误就说明这个格子不是1那么必然是2 , 如果没有出现错误 , 第二步循环下去还没有得出解 , 那么再进行穷举 ...
直到全部填完
代码:
import org.apache.commons.lang3.StringUtils;
public class shudu {
private static int exam_question[][] = new int[9][9];//数组形式题目
private static int exam_question_[][] = new int[9][9];//数组形式题目备份
private static int cyclic_num_time = 0;//排除无结果次数
private static int allow_num_time = 0;//计算空位允许值无结果次数
private static int allow_calcu_time = 0;//允许值排除次数
private static boolean all_stop = false;//结束标识
private static boolean is_exhaust = false;//穷举过程标识
private static int exhaust_time = 0;//穷举试探次数
private static boolean calculate_error = false;//穷举试探出现错误
//原始题目格式 , 便于手动写题
// private static final String question = "700000004050300000000000000000910500000000000408000090600048000010000360000070000";
// private static final String question = "930601400006429310140030069571096040428017906369004001693002104000143692214960000";
// private static final String question = "000000000000009300140000060500000040008007000009000001093000000000140002000060000";
private static final String question ="940010000001007408006500070080000700705406000000073015000200590058009006200050007"
;
private static String allow_value[][] = new String[9][9];//空位允许值
private static String allow_value_[][] = new String[9][9];//空位允许值备份
private static int empty_postion[][] = new int[9][9];//空位标识
private static int empty_postion_[][] = new int[9][9];//空位标识备份
//main方法入口
public static void main(String[] args) {
System.out.println("题目录入");
enter_question(question);
System.out.println("题目======================================================================");
dayin(exam_question);
long begin_time = System.currentTimeMillis();
System.out.println("进入初级阶段:通过规则排除确定每行每竖每个九宫格唯一值");
eliminate();
System.out.println("当前得到的部分答案集=========================================================");
dayin(exam_question);
if (!all_stop) {
System.out.println("进入中级阶段:遍历剩余每个空位的允许值");
allow_num_time = 0;
allow_value1();
dayin1(allow_value);
while (allow_num_time < 4 && !justend(true)) {
allow_value2();
allow_num_time++;
}
if (!all_stop) {
System.out.println("当下空位的允许值=======" +
"允许值排除成功次数:" + allow_calcu_time + "次====================================");
dayin1(allow_value);
System.out.println("当前得到的部分答案集=========================================================");
dayin(exam_question);
System.out.println("进入高级阶段:穷举");
is_exhaust = true;
long sun_time = System.currentTimeMillis();
while (!all_stop) {
jisuan();
long now_time = System.currentTimeMillis();
if (now_time - sun_time > 99999) {
System.out.println("计算超时 , 该数独可能没有正确解!");
break;
}
}
}
}
long end_time = System.currentTimeMillis();
System.out.println("答案======" +
"计算用时:" + (end_time - begin_time) + "毫秒======" +
"穷举试探次数:" + exhaust_time + "次======" +
"允许值排除成功次数:" + allow_calcu_time + "次======");
dayin(exam_question);
}
/**
* 初步根据 每行每竖每个九宫格中不重复的规则 确定唯一值
*/
private static void eliminate() {
//若无值次数到达9次 , 说明1-9整个循环下来都没有得到结果 , 如果所有值在这个阶段全部填完 , 也结束循环
while (cyclic_num_time < 9 && !justend(false)) {
for (int n = 1; n <= 9; n++) {
//复制空位临时值
for (int y = 0; y < 9; y++) {
for (int x = 0; x < 9; x++) {
empty_postion_[y][x] = empty_postion[y][x];
}
}
//初步排除必不为 n 的空位
for (int y = 0; y < 9; y++) {
for (int x = 0; x < 9; x++) {
if (exam_question[y][x] == n) {
//每行每竖
for (int i = 0; i < 9; i++) {
empty_postion_[y][i] = 0;
empty_postion_[i][x] = 0;
}
//每个九宫格
int _y = y / 3 * 3, y_ = _y + 3;
int _x = x / 3 * 3, x_ = _x + 3;
for (int y1 = _y; y1 < y_; y1++) {
for (int x1 = _x; x1 < x_; x1++) {
empty_postion_[y1][x1] = 0;
}
}
}
}
}
//判断每个小九宫格中的唯一值
for (int y = 0; y < 9; y += 3) {
for (int x = 0; x < 9; x += 3) {
int y_ = -1, x_ = -1, num = 0;
for (int y0 = y; y0 < y + 3; y0++) {
for (int x0 = x; x0 < x + 3; x0++) {
if (empty_postion_[y0][x0] == 1) {
y_ = y0;
x_ = x0;
num++;
}
}
}
if (num == 1) {
eliminate_only_one(y_, x_, n);
}
}
}
//判断每行每竖唯一值
for (int y1 = 0; y1 < 9; y1++) {
int y_0 = -1, x_0 = -1, sum_0 = 0, y_1 = -1, x_1 = -1, sum_1 = 0;
for (int x1 = 0; x1 < 9; x1++) {
if (empty_postion_[y1][x1] == 1) {
y_0 = y1;
x_0 = x1;
sum_0++;
}
if (empty_postion_[x1][y1] == 1) {
y_1 = x1;
x_1 = y1;
sum_1++;
}
}
if (sum_0 == 1) {
eliminate_only_one(y_0, x_0, n);
}
if (sum_1 == 1) {
eliminate_only_one(y_1, x_1, n);
}
}
}
cyclic_num_time++;
}
}
/**
* 初步排除阶段 输入确定值
*
* @param y 行
* @param x 列
* @param n 数
*/
private static void eliminate_only_one(int y, int x, int n) {
empty_postion[y][x] = 0;
exam_question[y][x] = n;
cyclic_num_time = 0;
empty_postion_[y][x] = 0;
//去除每行每竖虚空格
for (int i = 0; i < 9; i++) {
empty_postion_[y][i] = 0;
empty_postion_[i][x] = 0;
}
}
//初步计算当下每个空位可允许的值
private static void allow_value1() {
for (int y = 0; y < 9; y++) {
for (int x = 0; x < 9; x++) {
if (empty_postion[y][x] == 1) {
String man = "123456789";
for (int i = 0; i < 9; i++) {
man = man.replace(String.valueOf(exam_question[y][i]), "");
man = man.replace(String.valueOf(exam_question[i][x]), "");
}
int _y = y / 3 * 3, y_ = _y + 3;
int _x = x / 3 * 3, x_ = _x + 3;
for (int y1 = _y; y1 < y_; y1++) {
for (int x1 = _x; x1 < x_; x1++) {
man = man.replace(String.valueOf(exam_question[y1][x1]), "");
}
}
allow_value[y][x] = man;
}
}
}
}
/**
* 进一步计算当下每个空位可允许的值
*/
private static void allow_value2() {
for (int y = 0; y < 9; y++) {
for (int x = 0; x < 9; x++) {
String val = allow_value[y][x];
if (!StringUtils.isEmpty(val)) {
//当允许值只有一个时 , 直接填入
if (val.length() == 1) {
allow_value_change(null, y, x);
}
//当允许值存在两个时 , 查找每行每列每个九宫格与之相同的允许值空位 , 并排除相对其他位置的着两个元素
if (val.length() == 2) {
for (int i = y + 1; i < 9 - y; i++) {
String vv = allow_value[i][x];
if (!StringUtils.isEmpty(vv) && val.equals(vv)) {
//删除必不为元素
for (int j = 0; j < 9; j++) {
if (j == y || j == i) continue;
allow_value_change(val, j, x);
}
}
}
for (int i = x + 1; i < 9 - x; i++) {
String vv = allow_value[y][i];
if (!StringUtils.isEmpty(vv) && val.equals(vv)) {
//删除必不为元素
for (int j = 0; j < 9; j++) {
if (j == x || j == i) continue;
allow_value_change(val, y, j);
}
}
}
int _y = y / 3 * 3, y_ = _y + 3;
int _x = x / 3 * 3, x_ = _x + 3;
for (int y1 = _y; y1 < y_; y1++) {
for (int x1 = _x; x1 < x_; x1++) {
if (y1 <= y && x1 <= x) continue;
String vv = allow_value[y1][x1];
if (!StringUtils.isEmpty(vv) && val.equals(vv)) {
//删除必不为元素
for (int y2 = _y; y2 < y_; y2++) {
for (int x2 = _x; x2 < x_; x2++) {
if ((y2 == y && x2 == x) || (y2 == y1 && x2 == x1)) continue;
allow_value_change(val, y2, x2);
}
}
}
}
}
}
//当允许值存在三个时 , 每行每列每个九宫格若存在类似123,123,12或123,123,123的存在值形式 , 说明只有此三个空位允许填入123 , 则消除其他空位的123
if (val.length() == 3) {
for (int i = y + 1; i < 9; i++) {
String vv = allow_value[i][x];
if (val.equals(vv)) {
for (int j = 0; j < 9; j++) {
if (j == y || j == i) continue;
String pp = allow_value[j][x];
if (!StringUtils.isEmpty(pp) && pp.length() > 1 && pp.length() < 4) {
for (int k = 0; k < 3; k++) {
pp = pp.replace(val.substring(k, k + 1), "");
}
if (StringUtils.isEmpty(pp)) {
for (int m = 0; m < 9; m++) {
if (m == y || m == i || m == j) continue;
allow_value_change(val, m, x);
}
}
}
}
}
}
for (int i = x + 1; i < 9; i++) {
String vv = allow_value[y][i];
if (val.equals(vv)) {
for (int j = 0; j < 9; j++) {
if (j == x || j == i) continue;
String pp = allow_value[y][j];
if (!StringUtils.isEmpty(pp) && pp.length() > 1 && pp.length() < 4) {
for (int k = 0; k < 3; k++) {
pp = pp.replace(val.substring(k, k + 1), "");
}
if (StringUtils.isEmpty(pp)) {
for (int m = 0; m < 9; m++) {
if (m == x || m == i || m == j) continue;
allow_value_change(val, y, m);
}
}
}
}
}
}
int _y = y / 3 * 3, y_ = _y + 3;
int _x = x / 3 * 3, x_ = _x + 3;
for (int y1 = _y; y1 < y_; y1++) {
for (int x1 = _x; x1 < x_; x1++) {
if (y1 <= y && x1 <= x) continue;
String vv = allow_value[y1][x1];
if (val.equals(vv)) {
for (int y2 = _y; y2 < y_; y2++) {
for (int x2 = _x; x2 < x_; x2++) {
if ((y2 == y && x2 == x) || (y2 == y1 && x2 == x1)) continue;
String pp = allow_value[y2][x2];
if (!StringUtils.isEmpty(pp) && pp.length() > 1 && pp.length() < 4) {
for (int k = 0; k < 3; k++) {
pp = pp.replace(val.substring(k, k + 1), "");
}
if (StringUtils.isEmpty(pp)) {
for (int y3 = _y; y3 < y_; y3++) {
for (int x3 = _x; x3 < x_; x3++) {
if ((y3 == y && x3 == x) || (y3 == y1 && x3 == x1) || (y3 == y2 && x3 == x2))
continue;
allow_value_change(val, y3, x3);
}
}
}
}
}
}
}
}
}
}
//类似1234,1234,1234,12或1234,1234,1234,123或1234,1234,1234,1234的情况机率过小
//故暂时不采取相关计算 ,减小计算成本 , 若有可自行添加4位以上的运算
}
}
}
//当九宫格内允许填入n的空位只有一个时 , 直接填入n
for (int y = 0; y < 9; y += 3) {
for (int x = 0; x < 9; x += 3) {
for (int i = 1; i <= 9; i++) {
String ii = String.valueOf(i);
Integer y_ = null, x_ = null;
Integer y_x = null;
Integer x_y = null;
int y_n = 0, x_n = 0;
for (int y0 = 0; y0 < 3; y0++) {
for (int x0 = 0; x0 < 3; x0++) {
int y1 = y + y0, x1 = x + x0;
String val = allow_value[y1][x1];
if (!StringUtils.isEmpty(val)) {
//如果为穷举步骤
if (val.indexOf(ii) != -1) {
if (y_ == null || y_.equals(y1)) {
y_ = y1;
y_x = x1;
y_n++;
} else {
y_ = -1;
}
if (x_ == null || x_.equals(x1)) {
x_ = x1;
x_y = y1;
x_n++;
} else {
x_ = -1;
}
}
}
}
}
if (y_ != null && y_ != -1) {
if (y_n > 1) {
for (int x2 = 0; x2 < 9; x2++) {
if (x2 != x && x2 != x + 1 && x2 != x + 2) {
String vv = allow_value[y_][x2];
if (!StringUtils.isEmpty(vv) && vv.indexOf(ii) != -1) {
vv = vv.replace(ii, "");
allow_value[y_][x2] = vv;
}
}
}
} else if (y_n == 1) {
allow_value[y_][y_x] = ii;
allow_value_change(null, y_, y_x);
}
}
if (x_ != null && x_ != -1) {
if (x_n > 1) {
for (int y2 = 0; y2 < 9; y2++) {
if (y2 != y && y2 != y + 1 && y2 != y + 2) {
String vv = allow_value[y2][x_];
if (!StringUtils.isEmpty(vv) && vv.indexOf(ii) != -1) {
vv = vv.replace(ii, "");
allow_value[y2][x_] = vv;
}
}
}
} else if (x_n == 1) {
allow_value[x_y][x_] = ii;
allow_value_change(null, x_y, x_);
}
}
}
}
}
}
/**
* 遍历允许值阶段当前空位允许值 变化 , 并消除相关其他位置的允许值replace
*
* @param replace 需要排除的允许值
* @param y y
* @param x x
*/
private static void allow_value_change(String replace, int y, int x) {
String val = allow_value[y][x], val2 = val;
if (!StringUtils.isEmpty(val)) {
if (!StringUtils.isEmpty(replace)) {
for (int k = 0; k < replace.length(); k++) {
val = val.replace(replace.substring(k, k + 1), "");
}
}
//当空位允许值发生改变
if (!val2.equals(val) || val.length() == 1) {
allow_calcu_time++;
allow_num_time = 0;
//若允许值只有一个
if (val.length() == 1) {
allow_value[y][x] = null;
exam_question[y][x] = Integer.valueOf(val);
empty_postion[y][x] = 0;
for (int k = 0; k < 9; k++) {
if (k != x) {
String rr = allow_value[y][k];
if (!StringUtils.isEmpty(rr)) {
allow_value[y][k] = rr.replace(val, "");
}
}
if (k != y) {
String rr = allow_value[k][x];
if (!StringUtils.isEmpty(rr)) {
allow_value[k][x] = rr.replace(val, "");
}
}
}
int _y = y / 3 * 3, y_ = _y + 3;
int _x = x / 3 * 3, x_ = _x + 3;
for (int y1 = _y; y1 < y_; y1++) {
for (int x1 = _x; x1 < x_; x1++) {
String rr = allow_value[y1][x1];
if (!StringUtils.isEmpty(rr)) {
rr = rr.replace(String.valueOf(val), "");
allow_value[y1][x1] = rr;
}
}
}
} else {
allow_value[y][x] = val;
}
//查找穷举试探错误
if (is_exhaust) {
calculate_error = justerror();
}
}
}
}
//穷举试探当前空位值
private static void jisuan() {
int y0 = -1, x0 = -1;
String val_0 = "";
//备份空位集合 , 答案路径集合 , 允许值集合 , 便于回滚数据 , 并选取允许值为两位的空位进行穷举
for (int y = 0; y < 9; y++) {
for (int x = 0; x < 9; x++) {
empty_postion_[y][x] = empty_postion[y][x];
exam_question_[y][x] = exam_question[y][x];
String val = allow_value_[y][x] = allow_value[y][x];
if (!StringUtils.isEmpty(val) && val.length() == 2) {
y0 = y;
x0 = x;
val_0 = val;
}
}
}
if (!StringUtils.isEmpty(val_0)) {
//初步试探成功标识
boolean print_flag = true;
exhaust_time++;
//选取允许值的第一个作为试探值
System.out.println("穷举选取:第 " + (y0 + 1) + " 行第 " + (x0 + 1) + " 列元素允许值 " + val_0 + " 试探值为 " + val_0.substring(0, 1));
String val_1 = val_0.substring(0, 1);
allow_value[y0][x0] = val_1;
allow_value_change(null, y0, x0);
allow_num_time = 0;
while (allow_num_time < 3 && !justend(true)) {
//如果此试探值走不通则换一个试探值
if (calculate_error) {
//初步试探错误 , 重新选取允许值的第二位作为试探值
print_flag = false;
calculate_error = false;
System.out.println("穷举排除:试探出现错误,第 " + (y0 + 1) + " 行第 " + (x0 + 1) + " 列元素 " + val_0 + " 被排除值 " + val_0.substring(0, 1) + " 被确定为 " + val_0.substring(1, 2));
//回滚数据
for (int y = 0; y < 9; y++) {
for (int x = 0; x < 9; x++) {
empty_postion[y][x] = empty_postion_[y][x];
exam_question[y][x] = exam_question_[y][x];
allow_value[y][x] = allow_value_[y][x];
}
}
//放入确定值
val_1 = val_0.substring(1, 2);
allow_value[y0][x0] = val_1;
allow_value_change(null, y0, x0);
while (allow_num_time < 3 && !justend(true)) {
allow_value2();
allow_num_time++;
}
break;
}
allow_value2();
allow_num_time++;
}
//若初步试探成功
if (print_flag) {
System.out.println("穷举确定:试探无错误,第 " + (y0 + 1) + " 行第 " + (x0 + 1) + " 列元素 " + val_0 + " 被确定为 " + val_0.substring(0, 1));
}
}
}
//题目录入
private static void enter_question(String question_) {
char[] arr = question_.toCharArray();
for (int y = 0, n = 0; y < 9; y++) {
for (int x = 0; x < 9; x++) {
int sun = Integer.valueOf(String.valueOf(arr[n]));
exam_question[y][x] = sun;
//计入空位
if (sun == 0)
empty_postion[y][x] = 1;
else
empty_postion[y][x] = 0;
n++;
}
}
}
//判断总体结束
private static boolean justend(boolean all) {
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
if ((all && !StringUtils.isEmpty(allow_value[i][j])) || (!all && empty_postion[i][j] > 0)) {
return false;
}
}
}
all_stop = true;
return true;
}
//判断穷举试探路径错误
private static boolean justerror() {
for (int i = 0; i < 9; i++) {
String heng = "123456789";
int heng_ = 0;
String shu = "123456789";
int shu_ = 0;
for (int j = 0; j < 9; j++) {
String ooheng = allow_value[i][j];
if (!StringUtils.isEmpty(ooheng)) {
for (int k = 0; k < ooheng.length(); k++) {
heng = heng.replace(ooheng.substring(k, k + 1), "");
}
heng_++;
}
String ooshu = allow_value[j][i];
if (!StringUtils.isEmpty(ooshu)) {
for (int k = 0; k < ooshu.length(); k++) {
shu = shu.replace(ooshu.substring(k, k + 1), "");
}
shu_++;
}
}
if (9 - heng.length() != heng_ || 9 - shu.length() != shu_) {
return true;
}
}
for (int y = 0; y < 9; y += 3) {
for (int x = 0; x < 9; x += 3) {
String heng = "123456789";
int heng_ = 0;
for (int y0 = 0; y0 < 3; y0++) {
for (int x0 = 0; x0 < 3; x0++) {
int y1 = y + y0, x1 = x + x0;
String val = allow_value[y1][x1];
if (!StringUtils.isEmpty(val)) {
for (int k = 0; k < val.length(); k++) {
heng = heng.replace(val.substring(k, k + 1), "");
}
heng_++;
}
}
}
if (9 - heng.length() != heng_) {
return true;
}
}
}
return false;
}
//打印2
private static void dayin(int[][] kk) {
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(" | ");
if (kk[i][j] == 0)
System.out.print(" _ ");
else
System.out.print(" " + kk[i][j] + " ");
}
System.out.println("|");
}
System.out.println(" ------------------------------------");
// for (int i = 0; i < 9; i++) {
// for (int j = 0; j < 9; j++) {
// System.out.print(kk[i][j]);
// }
// }
}
//打印2
private static void dayin1(String[][] kk) {
System.out.println();
String m = " ";
System.out.print(" ");
for (int j = 1; j <= 9; j++) {
System.out.print(" |" + j + m);
}
System.out.println();
for (int i = 0; i < 9; i++) {
if (i % 3 == 0)
System.out.println("============================================================================================");
else
System.out.println("--------------------------------------------------------------------------------------------");
System.out.print(i + 1 + " ");
System.out.print("| ");
for (int j = 0; j < 9; j++) {
if (StringUtils.isEmpty(kk[i][j]))
System.out.print(m + " | ");
else {
String oo = "";
int len = String.valueOf(kk[i][j]).length();
for (int o = 0; o < 5 - len; o++) {
oo += " ";
}
System.out.print(kk[i][j] + oo + " | ");
}
}
System.out.println();
}
System.out.println("===============================================================================================");
System.out.println();
}
}
控制台打印输出:
题目录入
题目======================================================================
------------------------------------
| 9 4 _ | _ 1 _ | _ _ _ |
| _ _ 1 | _ _ 7 | 4 _ 8 |
| _ _ 6 | 5 _ _ | _ 7 _ |
------------------------------------
| _ 8 _ | _ _ _ | 7 _ _ |
| 7 _ 5 | 4 _ 6 | _ _ _ |
| _ _ _ | _ 7 3 | _ 1 5 |
------------------------------------
| _ _ _ | 2 _ _ | 5 9 _ |
| _ 5 8 | _ _ 9 | _ _ 6 |
| 2 _ _ | _ 5 _ | _ _ 7 |
------------------------------------
进入初级阶段:通过规则排除确定每行每竖每个九宫格唯一值
当前得到的部分答案集=========================================================
------------------------------------
| 9 4 7 | _ 1 _ | _ 5 _ |
| 5 _ 1 | _ _ 7 | 4 _ 8 |
| 8 _ 6 | 5 _ _ | _ 7 _ |
------------------------------------
| _ 8 _ | 1 _ 5 | 7 _ _ |
| 7 1 5 | 4 _ 6 | _ _ _ |
| _ _ _ | _ 7 3 | _ 1 5 |
------------------------------------
| _ 7 _ | 2 _ _ | 5 9 _ |
| _ 5 8 | 7 _ 9 | _ _ 6 |
| 2 _ _ | _ 5 _ | _ _ 7 |
------------------------------------
进入中级阶段:遍历剩余每个空位的允许值
|1 |2 |3 |4 |5 |6 |7 |8 |9
============================================================================================
1 | | | | 368 | | 28 | 236 | | 23 |
--------------------------------------------------------------------------------------------
2 | | 23 | | 369 | 2369 | | | 236 | |
--------------------------------------------------------------------------------------------
3 | | 23 | | | 2349 | 24 | 1239 | | 1239 |
============================================================================================
4 | 346 | | 2349 | | 29 | | | 2346 | 2349 |
--------------------------------------------------------------------------------------------
5 | | | | | 289 | | 2389 | 238 | 239 |
--------------------------------------------------------------------------------------------
6 | 46 | 269 | 249 | 89 | | | 2689 | | |
============================================================================================
7 | 1346 | | 34 | | 3468 | 148 | | | 134 |
--------------------------------------------------------------------------------------------
8 | 134 | | | | 34 | | 123 | 234 | |
--------------------------------------------------------------------------------------------
9 | | 369 | 349 | 368 | | 148 | 138 | 348 | |
===============================================================================================
当下空位的允许值=======允许值排除成功次数:4次====================================
|1 |2 |3 |4 |5 |6 |7 |8 |9
============================================================================================
1 | | | | 368 | | 28 | 236 | | 23 |
--------------------------------------------------------------------------------------------
2 | | 23 | | 369 | 369 | | | 236 | |
--------------------------------------------------------------------------------------------
3 | | 23 | | | 34 | 24 | 19 | | 19 |
============================================================================================
4 | 36 | | 239 | | 29 | | | 246 | 249 |
--------------------------------------------------------------------------------------------
5 | | | | | 289 | | 2389 | 238 | 239 |
--------------------------------------------------------------------------------------------
6 | 46 | 69 | 249 | 89 | | | 2689 | | |
============================================================================================
7 | 1346 | | 34 | | 3468 | 148 | | | 134 |
--------------------------------------------------------------------------------------------
8 | 134 | | | | 34 | | 123 | 234 | |
--------------------------------------------------------------------------------------------
9 | | 69 | 349 | 36 | | 14 | 138 | 348 | |
===============================================================================================
当前得到的部分答案集=========================================================
------------------------------------
| 9 4 7 | _ 1 _ | _ 5 _ |
| 5 _ 1 | _ _ 7 | 4 _ 8 |
| 8 _ 6 | 5 _ _ | _ 7 _ |
------------------------------------
| _ 8 _ | 1 _ 5 | 7 _ _ |
| 7 1 5 | 4 _ 6 | _ _ _ |
| _ _ _ | _ 7 3 | _ 1 5 |
------------------------------------
| _ 7 _ | 2 _ _ | 5 9 _ |
| _ 5 8 | 7 _ 9 | _ _ 6 |
| 2 _ _ | _ 5 _ | _ _ 7 |
------------------------------------
进入高级阶段:穷举
穷举选取:第 9 行第 6 列元素允许值 14 试探值为 1
穷举确定:试探无错误,第 9 行第 6 列元素 14 被确定为 1
穷举选取:第 9 行第 7 列元素允许值 38 试探值为 3
穷举确定:试探无错误,第 9 行第 7 列元素 38 被确定为 3
答案======计算用时:102毫秒======穷举试探次数:2次======允许值排除成功次数:69次======
------------------------------------
| 9 4 7 | 3 1 8 | 6 5 2 |
| 5 2 1 | 9 6 7 | 4 3 8 |
| 8 3 6 | 5 4 2 | 1 7 9 |
------------------------------------
| 3 8 9 | 1 2 5 | 7 6 4 |
| 7 1 5 | 4 9 6 | 8 2 3 |
| 4 6 2 | 8 7 3 | 9 1 5 |
------------------------------------
| 6 7 3 | 2 8 4 | 5 9 1 |
| 1 5 8 | 7 3 9 | 2 4 6 |
| 2 9 4 | 6 5 1 | 3 8 7 |
------------------------------------