1. 程式人生 > >數獨遊戲解法

數獨遊戲解法

  數獨遊戲解法

  深搜(棧實現)

  難過的是我時間來不及了,唉...

  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--; //進行填數的位置回退一個 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 }