1 /** 2 * Sudoku 3 * @author Victor 4 * @date 2013-7-10 上午8:47:44 5 */ 6 public class Sudoku { 7 8 public static void main(String[] args) { 9 // TODO Auto-generated method stub 10 String input = "....3..9....2....1.5.9..............1.2.8.4.6.8.5...2..75......4.1..6..3.....4.6."; 11 System.out.println(input); 12 String out = new Sudoku().sudoku(input); 13 if(out == null) { 14 System.out.println("failed."); 15 } else { 16 System.out.println(out); 17 } 18 } 19 20 private final static int MAX = 9; 21 private int[][] input(String in) { 22 final int[][] matrix = new int[MAX][MAX]; 23 for (int i = 0; i < MAX; i++) { 24 for (int j = 0; j < MAX; j++) { 25 char c = in.charAt(MAX * i + j); 26 if(c == '.') { 27 matrix[i][j] = 0; 28 } else { 29 matrix[i][j] = Integer.parseInt(String.valueOf(c)); 30 } 31 } 32 } 33 return matrix; 34 } 35 36 private String output(final int[][] matrix) { 37 StringBuilder out = new StringBuilder(); 38 for (int i = 0; i < MAX; i++) { 39 for (int j = 0; j < MAX; j++) { 40 out.append(matrix[i][j]); 41 } 42 } 43 return out.toString(); 44 } 45 46 private String sudoku(String input) { 47 // input matrix 48 int[][] originalMatrix = input(input); 49 int[][] detectMatrix = input(input); 50 51 if(sudokuRecursive(originalMatrix, detectMatrix, 0)) { 52 return output(detectMatrix); 53 } 54 55 return null; 56 } 57 58 /** 59 * 递归求解 60 * @author Victor 61 * @date 2013-7-10 下午9:10:09 62 * @param originalMatrix 原输入矩阵 63 * @param detectMatrix 探测矩阵,存放每一个位置的探测结果 64 * @param pos 当前探测的位置 65 * @return boolean 是否成功 66 */ 67 private boolean sudokuRecursive(int[][] originalMatrix, int[][] detectMatrix, int pos) { 68 int x = pos / MAX; 69 int y = pos % MAX; 70 if(pos == 81) { 71 return true; 72 } 73 if(originalMatrix[x][y] == 0) { 74 for(int c = 1; c < MAX + 1; c++) { 75 if(isAllowed(x, y, c, detectMatrix)) { 76 detectMatrix[x][y] = c; 77 if(sudokuRecursive(originalMatrix, detectMatrix, pos + 1)) 78 return true; 79 } 80 } 81 detectMatrix[x][y] = 0; 82 return false; 83 } else { 84 detectMatrix[x][y] = originalMatrix[x][y]; 85 if(sudokuRecursive(originalMatrix, detectMatrix, pos + 1)) 86 return true; 87 } 88 return false; 89 } 90 91 /** 92 * Check在(x,y)位置是否可以放置candidate 93 * @author Victor 94 * @date 2013-7-8 下午7:20:00 95 * @param x x坐标 0,1,2....8 96 * @param y y坐标 0,1,2....8 97 * @param candidate 候选数字 98 * @param matrix 输入矩阵 99 * @return boolean 是否允许放置该数字 100 */ 101 private static boolean isAllowed(final int x, final int y, final int candidate, final int[][] matrix) { 102 return allowInRow(x, candidate, matrix) && allowInColumn(y, candidate, matrix) && allowInUnit(x, y, candidate, matrix); 103 } 104 105 private static boolean allowInRow(final int x, final int candidate, final int[][] matrix) { 106 for(int y = 0; y < MAX; y++) { 107 // y is immutable 108 if(candidate == matrix[x][y]) 109 return false; 110 } 111 return true; 112 } 113 114 private static boolean allowInColumn(final int y, final int candidate, final int[][] matrix) { 115 for(int x = 0; x < MAX; x++) { 116 // x is immutable 117 if(candidate == matrix[x][y]) 118 return false; 119 } 120 return true; 121 } 122 123 private static boolean allowInUnit(final int x, final int y, final int candidate, final int[][] matrix) { 124 // 0,1,2 to 0; 3,4,5 to 1; 6,7,8 to 2 125 int xScale = x / 3; 126 int yScale = y / 3; 127 for(int m = xScale * 3; m < (xScale + 1) * 3; m++) { 128 for(int n = yScale * 3; n < (yScale + 1) * 3; n++) { 129 // x is in [xScale * 3, (xScale + 1) * 3), y is in [yScale * 3, (yScale + 1) * 3) 130 if(candidate == matrix[m][n]) 131 return false; 132 } 133 } 134 return true; 135 } 136 }

浙公网安备 33010602011771号