java求解数独(递归)
来源:互联网 发布:种植牙植体品牌 知乎 编辑:程序博客网 时间:2024/06/06 02:52
/**
* 先来一些测试用例
* 0 0 0 0 0 0 0 0 0
* 0 0 0 0 0 0 0 0 0
* 0 0 0 0 0 0 0 0 0
* 0 0 0 0 0 0 0 0 0
* 0 0 0 0 0 0 0 0 0
* 0 0 0 0 0 0 0 0 0
* 0 0 0 0 0 0 0 0 0
* 0 0 0 0 0 0 0 0 0
* 0 0 0 0 0 0 0 0 0
*
* 6 0 0 4 0 0 0 8 0
* 0 0 1 0 0 7 9 0 6
* 0 0 9 2 0 0 4 0 0
* 0 0 5 3 1 0 2 0 0
* 0 9 0 0 0 8 0 1 0
* 0 0 3 7 0 0 5 0 0
* 0 0 6 0 0 3 1 0 0
* 7 0 8 6 0 0 3 0 0
* 0 3 0 0 0 5 0 0 2
*
* 7 2 6 9 0 4 0 5 1
* 0 8 0 6 0 7 4 3 2
* 3 4 1 0 8 5 0 0 9
* 0 5 2 4 6 8 0 0 7
* 0 3 7 0 0 0 6 8 0
* 0 9 0 0 0 3 0 1 0
* 0 0 0 0 0 0 0 0 0
* 9 0 0 0 2 1 5 0 0
* 8 0 0 3 0 0 0 0 0
*
* 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
*/
public class Test { private static int count = 0; private static int trys = 0; private static int trys2 = 0; private static long end; private static boolean found = true; public static void main(String[] args) { Scanner scanner = new Scanner(System.in); int length = 9; int[][] arr = new int[length][length]; for (int i = 0; i < length; i++) { String line = scanner.nextLine(); for (int j = 0; j < line.split(" ").length; j++) { arr[i][j] = Integer.parseInt(line.split(" ")[j]); } } long start = System.nanoTime(); execute(arr, true); System.out.println("总共有:" + count + " 种组合!尝试了:" + trys + "种组合.其中尝试" + trys2 + "种找到第一个结果!总耗时:" + (System.nanoTime() - start) / 1000000 + "ms," + "其中第一例耗时:" + (end - start) / 1000000 + "ms"); } /** * h 纵 * w 横 * * @param arr * @return */ public static String execute(int[][] arr, boolean first) { int[] zero = getZero(arr); if (zero == null) { return print(arr); } Integer[] canUse = getSomething(arr, zero); if (canUse == null || canUse.length < 1) { return "error"; } for (int num : canUse) { trys++; arr[zero[0]][zero[1]] = num; if (first) { System.out.println("============================>>" + Arrays.toString(canUse) + "now try to set arr[" + zero[0] + "][" + zero[1] + "]=" + num); } String result = execute(arr, false); if (!"error".equals(result)) { System.out.println("===============" + (++count) + "=================" + "\r\n" + result); if (found) { end = System.nanoTime(); trys2 = trys; } found = false; } arr[zero[0]][zero[1]] = 0;//还原 } return "error"; } private static int[] getZero(int[][] arr) { for (int h = 0; h < arr.length; h++) { for (int w = 0; w < arr[h].length; w++) { if (0 == arr[h][w]) { return new int[]{h, w}; } } } return null; } private static String print(int[][] arr) { StringBuilder sb = new StringBuilder(); for (int h = 0; h < arr.length; h++) { for (int w = 0; w < arr[h].length - 1; w++) { sb.append(arr[h][w]).append(" "); } sb.append(arr[h][arr[h].length - 1]).append("\r\n"); } return sb.toString().substring(0, sb.length() - 2); } private static Integer[] getSomething(int[][] arr, int[] zero) { int[] all = new int[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; int[] temp = getBlock(arr, zero[0], zero[1]); for (int i = 0; i < arr.length; i++) { all[arr[zero[0]][i]] = 0; all[arr[i][zero[1]]] = 0; all[temp[i]] = 0; } List<Integer> list = new ArrayList<>(); for (int i = 0; i < all.length; i++) { if (0 != all[i]) { list.add(all[i]); } } Object[] objects = list.toArray(); Integer[] ret = new Integer[objects.length]; return list.toArray(ret); } private static int[] getBlock(int[][] arr, int h, int w) { int blockId = getBlockId(h, w); h = (int) Math.ceil(blockId / 3.0);//第几行开始 w = blockId % 3 == 0 ? 3 : blockId % 3;//第几列开始 int[] temp = new int[9]; for (int j = 0; j < 3; j++) { for (int k = 0; k < 3; k++) { temp[j * 3 + k] = arr[(h - 1) * 3 + j][(w - 1) * 3 + k]; } } return temp; } private static int getBlockId(int h, int w) { return ((h < 3 ? 1 : h < 6 ? 2 : 3) - 1) * 3 + (w < 3 ? 1 : w < 6 ? 2 : 3); }}
看到这个是华为的面试题,觉得有点意思,就花了点时间写了(最后花了大概4个小时T_T惭愧T_T)。大学刚毕业,做个纪念,以后越来越好!!!
- java求解数独(递归)
- 数独 递归求解(C语言)
- 数独求解java
- 递归求解九宫格(数独)源代码
- 数独游戏求解(递归+回溯)
- java数独生成算法(递归)
- 数独求解(回溯)
- 数独求解(深搜)
- 数独求解----回溯递归,无脑枚举版
- 数独(Sudoku)求解程序
- 数独求解(C++代码)
- 数独游戏求解
- 求解数独
- 数独求解算法
- 求解数独
- 数独求解
- 数独算法求解
- 数独求解算法
- java.lang.Thread 和 java.lang.Runnable的区别
- App反编译小结
- iOS中常见的----------------NSAttributedString
- linux基础二
- Hash树Trie树详解及其应用
- java求解数独(递归)
- POJ-3080 Blue Jeans(简单字符串)
- 微博分享不成功 Failed to find provider info for com.sina.weibo.sdkProvider
- web前端js跨域的两种实现方式jsonp和src
- iOS与H5交互
- MyEclipse+Tomcat+MAVEN+SVN项目完整环境搭建
- 点、圆、圆柱类的设计
- Mysql索引
- Java设计模式之单例模式