数独游戏解法
数独游戏解法
深搜(栈实现)
1 import java.util.*; 2 3 class Point{ 4 int x, y, num; 5 public Point(int x, int y, int num){ 6 this.x = x; 7 this.y = y; 8 this.num = num; 9 } 10 public Point(int x, int y){ 11 this(x, y, 0); 12 } 13 public String toString(){ 14 return "(" + x + "," + y + ")"; 15 } 16 } 17 18 public class Main{ 19 static Scanner sc = new Scanner(System.in); 20 21 static boolean check(int[][] map, Point p){ 22 if(p.num == 0) //要填的数不能是0 23 return false; 24 25 for(int j = 0; j < 9; j++) //判断该位置所在行和列是否存在与要填数字相同的数 26 if(map[p.x][j] == p.num || map[j][p.y] == p.num) 27 return false; 28 29 int[] d = {0,3,6,9}; //数独图的4条边界线 30 for(int i = 1; i < 4; i++){ 31 if(p.x < d[i]){ //判断行位置 32 for(int j = 1; j < 4; j++){ 33 if(p.y < d[j]){ //判断列位置 34 //开始判断对应九宫格里是否存在与要填数字相同的数 35 for(int k = d[i-1]; k < d[i]; k++){ 36 for(int l = d[j-1]; l < d[j]; l++) 37 if(map[k][l] == p.num) 38 return false; 39 } 40 break; //列只需对应一个位置 41 } 42 } 43 break; //行只需对应一个位置 44 } 45 } 46 return true; 47 } 48 49 static void out(int[][] map, String s){ //查看数独图,s为间隔符 50 for(int i = 0; i < 9; i++){ 51 for(int j = 0; j < 9; j++) 52 System.out.print(map[i][j] + s); 53 System.out.println(); 54 } 55 } 56 57 public static void main(String[] args) { 58 while(sc.hasNext()){ 59 int n = sc.nextInt(), id = 1; //进行n次数独 60 if(n == 0) break; 61 while(n-- != 0){ 62 int[][] map = new int[9][9]; 63 Point[] p = new Point[81]; 64 int pnum = 0; 65 for(int i = 0; i < 9; i++){ //输入处理 66 String s = sc.next(); 67 for(int j = 0; j < 9; j++){ 68 map[i][j] = s.charAt(j) - '0'; 69 if(map[i][j] == 0) 70 p[pnum++] = new Point(i, j); 71 } 72 } 73 // out(map, " "); //查看数独图内情况 74 // 75 // for(int i = 0; i < pnum; i++) //查看需要填数的位置 76 // System.out.println(p[i]); 77 78 Stack<Point> stack = new Stack<Point>(); 79 int t = 0; 80 // int max = 0; //尝试填数次数 81 stack.push(p[0]); //将第一个需要填数的位置入栈 82 while(!stack.isEmpty() && t < pnum){ 83 Point p1 = stack.pop(); //将要填的位置拿出来,进行赋值 84 85 while(p1.num < 10){ //从p1.num(若无赋值,初始为0)到9,确定一个可以填的数 86 if(check(map, p1)){ //判断该位置填p1.num这个数是否合理 87 map[p1.x][p1.y] = p1.num; //将该位置的数填好 88 stack.push(p1); //合理就入栈这个位置,并存住了该位置判断到的数值(p1.num) 89 if(++t < pnum){ //放入下一个要进行填数的位置的前置判断 90 p[t].num = 1; //将数值初始为1; 91 stack.push(p[t]); //放入下一个要进行填数的位置 92 } 93 // max++; //尝试次数+1 94 break; //数字合理就可以直接跳出循环 95 } 96 p1.num++; //如果p1.num不合理,则将p1.num+1,再进行判断 97 } 98 if(p1.num == 10){ //p1.num达到10,说明上一个位置不应该保存,去除此位置,继续判断上一个位置 99 map[p1.x][p1.y] = 0; //将这个位置填的数取消 100 t--; //进行填数的位置回退一个,而上一个格子的数字在图上已填过,会被九宫格判断返回false后+1 101 } 102 // out(map," "); //查看数独的过程 103 // System.out.println("--------"+max+"--------"); 104 105 } 106 System.out.println("case "+ id++ +": "); //输出数独结果 107 out(map,""); 108 // System.out.println(); 109 } 110 } 111 System.gc();sc.close(); 112 } 113 }
作 者:月 暮
出 处:https://www.cnblogs.com/AardWolf/
特此声明:欢迎园子的大大们指正错误,共同进步。如有问题或建议,也请各位大佬多多赐教!如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。
版权声明:本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接。
出 处:https://www.cnblogs.com/AardWolf/
特此声明:欢迎园子的大大们指正错误,共同进步。如有问题或建议,也请各位大佬多多赐教!如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。
版权声明:本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接。