使用java算法解决世界最难数独,我这花费的时间是60ms,虽然我发现有些人可以做到40ms以内,可能是用c++写的,我这使用java给后来者一个借鉴吧,本人也不是写的很好,望各位批评指正。
总体思路就是先填一个数,然后再填一个数,每次都判断是否和数独规定冲突,冲突就回滚,然后继续算……
下面贴代码(一共两个类,不过多解释了)
package com.cy.sudoku;
public class Main {
public static void main(String[] args) {
// TODO Auto-generated method stub
int[][] sudokuform = new int[][]{
{8,0,0,0,0,0,0,0,0},
{0,0,3,6,0,0,0,0,0},
{0,7,0,0,9,0,2,0,0},
{0,5,0,0,0,7,0,0,0},
{0,0,0,0,4,5,7,0,0},
{0,0,0,1,0,0,0,3,0},
{0,0,1,0,0,0,0,6,8},
{0,0,8,5,0,0,0,1,0},
{0,9,0,0,0,0,4,0,0}
};
long startTime = System.currentTimeMillis();
new SudoKuUtils(sudokuform).sudoKu();
System.out.println( "总耗时:" + (System.currentTimeMillis() - startTime) + "ms");
}
}
package com.cy.sudoku;
import java.util.ArrayList;
import java.util.List;
public class SudoKuUtils {
// 待解决的数独表
private int[][] sudokuform;
// 我需要填写的答案的下标
private List answerI, answerJ;
private int[][] answer;
// 我需要填写的答案数
private int answerNum;
public SudoKuUtils(int[][] sudokuform) {
answerI = new ArrayList<>();
answerJ = new ArrayList<>();
this.sudokuform = sudokuform;
getAnswerIndex();
answerNum = answerI.size();
}
/**
* 获得需要填写答案的位置的下标,存入两个list
*/
public void getAnswerIndex() {
answerI.clear();
answerJ.clear();
int[] answerIndex = new int[3];
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
if (sudokuform[i][j] == 0) {
answerI.add(i);
answerJ.add(j);
}
}
}
}
/**
* 主要入口
*/
public void sudoKu() {
for (int i = 0; i < answerI.size(); i++) {
for (int a = 1; a < 10; a++) {
if (isOk((int) answerI.get(i), (int) answerJ.get(i), a)
&& a > sudokuform[(int) answerI.get(i)][(int) answerJ.get(i)]) {
sudokuform[(int) answerI.get(i)][(int) answerJ.get(i)] = a;
// System.out.println((int) answerI.get(i) + " " + (int)
// answerJ.get(i) + " " + a);
break;
} else if (a == 9) {
if (i == 0) {
System.out.println("无解");
return;
}
sudokuform[(int) answerI.get(i)][(int) answerJ.get(i)] = 0;
if (i < 1) {
i = i - 1;
} else {
i = i - 2;
}
break;
}
}
}
print(sudokuform);
}
/**
* 传入i( 行)j(列)以及填入的值,判断是否符合要求
*/
public boolean isOk(int i, int j, int answer) {
for (int n = 0; n < 9; n++) {
if (sudokuform[i][n] == answer) {
return false;
}
}
for (int n = 0; n < 9; n++) {
if (sudokuform[n][j] == answer) {
return false;
}
}
if (i <= 2) {
if (j <= 2) {
for (int n = 0; n < 3; n++) {
for (int m = 0; m < 3; m++) {
if (sudokuform[n][m] == answer) {
return false;
}
}
}
} else if (j <= 5) {
for (int n = 0; n < 3; n++) {
for (int m = 3; m < 6; m++) {
if (sudokuform[n][m] == answer) {
return false;
}
}
}
} else {
for (int n = 0; n < 3; n++) {
for (int m = 6; m < 9; m++) {
if (sudokuform[n][m] == answer) {
return false;
}
}
}
}
} else if (i <= 5) {
if (j <= 2) {
for (int n = 3; n < 6; n++) {
for (int m = 0; m < 3; m++) {
if (sudokuform[n][m] == answer) {
return false;
}
}
}
} else if (j <= 5) {
for (int n = 3; n < 6; n++) {
for (int m = 3; m < 6; m++) {
if (sudokuform[n][m] == answer) {
return false;
}
}
}
} else {
for (int n = 3; n < 6; n++) {
for (int m = 6; m < 9; m++) {
if (sudokuform[n][m] == answer) {
return false;
}
}
}
}
} else {
if (j <= 2) {
for (int n = 6; n < 9; n++) {
for (int m = 0; m < 3; m++) {
if (sudokuform[n][m] == answer) {
return false;
}
}
}
} else if (j <= 5) {
for (int n = 6; n < 9; n++) {
for (int m = 3; m < 6; m++) {
if (sudokuform[n][m] == answer) {
return false;
}
}
}
} else {
for (int n = 6; n < 9; n++) {
for (int m = 6; m < 9; m++) {
if (sudokuform[n][m] == answer) {
return false;
}
}
}
}
}
return true;
}
/**
* 输出二维数组
*
* @param a
*/
public void print(int[][] a) {
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
System.out.print(" " + a[i][j] + " ");
if (j == 8) {
System.out.println();
}
}
}
}
/**
* 输出一维数组
*
* @param a
*/
public void print(int[] a) {
for (int i = 0; i < 9; i++) {
System.out.print(" " + a[i] + " ");
}
}
}