zoukankan      html  css  js  c++  java
  • 数独游戏解法

      数独游戏解法

      深搜(栈实现)

      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 }
  • 相关阅读:
    【杂文】搞一个对拍程序
    【学习笔记】线段树详解(全)
    【杂文】5亿大质数表(5e8)
    【学习笔记】OI玄学道—代码坑点
    【题解】动态逆序对 [CQOI2011] [P3157] [BZOJ3295] [P1393]
    【题解】永无乡 [HNOI2012] [BZOJ2733] [P3224]
    【题解】晋升者计数 Promotion Counting [USACO 17 JAN] [P3605]
    【题解】古代猪文 [SDOI2010] [BZOJ1951] [P2480]
    【题解】PERIOD
    Navicat Premium 12连接ubuntu18 ,Mysql 5.7.27-0
  • 原文地址:https://www.cnblogs.com/AardWolf/p/10113134.html
Copyright © 2011-2022 走看看