代碼:
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 |
------------------------------------