昨天朋友给了个数独的题目.想了半天没想出来
就自己写了个java实现. 效率并不高. 跑了半分钟才跑出来,也可能跟打印那么多额外的信息有关系.
import java.awt.List;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Stack;
public class shudu {
//数独数组的初始数据
public static int[][] bb = { { 8, -1, -1, -1, -1, -1, -1, -1, -1 }, { -1, -1, 3, 6, -1, -1, -1, -1, -1 }, { -1, 7, -1, -1, 9, -1, 2, -1, -1 },
{ -1, 5, -1, -1, -1, 7, -1, -1, -1 }, { -1, -1, -1, -1, 4, 5, 7, -1, -1 }, { -1, -1, -1, 1, -1, -1, -1, 3, -1 },
{ -1, -1, 1, -1, -1, -1, -1, 6, 8 }, { -1, -1, 8, 5, -1, -1, -1, 1, -1 }, { -1, 9, -1, -1, -1, -1, 4, -1, -1 } };
public static Stack<vo> mysteps = new Stack<vo>();
public static void main(String[] args) {
shudu mShudu = new shudu();
vo start = mShudu.getBestPositon(bb);
mysteps.push(start);
mysteps.get(mysteps.size() - 1);
//计算过程
while (mysteps.size() > 0) {
vo current = mysteps.peek();
int[][] temp = new int[10][10];
copyArray(current.current, temp);
if (current.values.size() > 0) {
int value = current.values.pop();
System.out.println(current.values.size() + " dddd");
temp[current.position[0]][current.position[1]] = value;
vo result = mShudu.getBestPositon(temp); //没找到一个数据的时候将他添加到历史里面
if (result != null) {
mysteps.push(result);
if (result.values.size() > 0) {
if (check(result.current)) {
System.out.println("result is");
printResult(result, mysteps.size());
break;
}
}
}
printResult(mysteps.peek(), mysteps.size());
} else {
mysteps.pop(); //当这个数据的所有数字都被尝试过的时候 就弹出他.
}
}
}
//检查是不是找到正确结果
public static boolean check(int[][] c) {
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
if (c[i][j] < 0) {
return false;
}
}
}
return true;
}
//打印过程
public static void printResult(vo v, int size) {
System.out.println("-------------------------------------------");
System.out.println("step size " + size);
System.out.println("positon " + v.position[0] + " " + v.position[1]);
String value = "";
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
value += v.current[i][j] + "\t";
}
value += "\n";
}
System.out.println(value);
}
//数组复制.. 可能是双重数组.. 直接用系统复制 太坑人了...
public static void copyArray(int[][] from, int[][] to) {
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
to[i][j] = from[i][j];
}
}
}
//提高效率 , 以次找到可能数字最小的位置来运算
public vo getBestPositon(int[][] mymap) {
int score = 0;
vo best = null;
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
if (mymap[i][j] > 0) {
continue;
}
int ix = i % 3;
int ip = i / 3;
int jx = j % 3;
int jp = j / 3;
int myscore = 0;
ArrayList<Integer> unuse = new ArrayList<Integer>();
for (int p = 0; p < 3; p++) {
for (int b = 0; b < 3; b++) {
if (mymap[ip * 3 + p][jp * 3 + b] > 0) {
myscore += 1;
unuse.add(mymap[ip * 3 + p][jp * 3 + b]);
}
}
}
for (int p = 0; p < 9; p++) {
if (p < ip * 3 || p >= (ip * 3 + 3)) {
if (mymap[p][j] > 0) {
myscore += 1;
unuse.add(mymap[p][j]);
}
}
}
for (int b = 0; b < 9; b++) {
if (b < jp * 3 || b >= (jp * 3 + 3)) {
if (mymap[i][b] > 0) {
myscore += 1;
unuse.add(mymap[i][b]);
}
}
}
if (myscore > score) {
score = myscore;
// System.err.println(" " + myscore + " " + score + " " +
// unuse.size());
System.out.println(unuse);
best = new vo();
best.position = new int[] { i, j };
copyArray(mymap, best.current);
for (int l = 1; l < 10; l++) {
boolean b = true;
for (int m : unuse) {
if (l == m) {
b = false;
break;
}
}
if (b) {
best.values.add(l); //获取可能数据
}
}
}
}
}
if (best.values.size() > 0) {
System.out.println(best.values + " " + best.position[0] + " " + best.position[1]);
return best;
} else {
return null;
}
}
}
//一个数据对象
class vo {
public int[] position;
public int[][] current = new int[10][10];
Stack<Integer> values = new Stack<Integer>();
public vo() {
}
}