数独

数独


前言

数独
每个谜题都由一个在不同位置给与提示数字的9x9网格组成。游戏的目的是将空方格填上数字,使得每一行,每一列以及每一个3x3宫都没有重复的数字出现。

在这里插入图片描述


深搜解法(Java)

练习dfs的基础题目(如有错误欢迎评论指正谢谢)
每行都有注释嗷~
代码如下(示例):

import java.util.Arrays;
import java.util.Scanner;
public class 数独游戏 {
    public static void main(String[] args) {
//        dfs()
        Scanner sc = new Scanner(System.in);
//        sc.nextLine();
//        生成二维数组用于存储输入的数据
        char[][] chars = new char[9][];
//        循环读入数据
        for (int i = 0; i < 9; i++) {
            chars[i]=sc.nextLine().toCharArray();
        }
//        数据读入完成  开始dfs
        dfs(chars,0,0);
    }

    private static void dfs(char[][] chars, int x, int y) {
//        定义出口
//        当我的列已经达到9  说明已经dfs完成 将即得的结果进行打印输出
        if(x==9){
            print(chars);
//         程序递归了很多层  这里直接退出程序
            System.exit(0);
        }
//       找到了一个需要进行填数的位置
        if(chars[x][y]=='0'){
//            我们从1~9选一个进行填入
            for (int i = 1; i <=9; i++) {
//                对如填入的数据 要进行合法验证
                if(check(chars,x,y,i)){
//                    如果合法  那么这种状态已经既定  进行下一次的递归
                    chars[x][y] = (char) (i+'0');
//                  由于是9*9的矩阵 每一行结尾要进行换行 有一个巧妙的算法
//                    列数的增量就等于 行数加一再对9进行除法 这样就可以在算完第九个位置的时候 自动开始下一行
//                    行数的增量相对简单:加一后对9进行取余即可
                    dfs(chars,x+(y+1)/9,(y+1)%9);
                }
            }
//            这个循环走完 还没有找到相应该填的数字说明游戏进行到了死角  之前的某一步走错了 需要走其平行分支
//            所以进行回溯
            chars[x][y]='0';
        }else {
//            否则这个位置有值那么继续处理下一个位置即可
            dfs(chars,x+(y+1)/9,(y+1)%9);
        }
    }
//      简单的打印二维数据的方法
    private static void print(char[][] chars) {
        for (int i = 0; i < chars.length; i++) {
            System.out.println(Arrays.toString(chars[i]));
        }
    }
//  检查当前元素是否合法
    private static boolean check(char[][] chars, int x, int y, int k) {
        for (int i  = 0; i <chars[0].length; i++) {
//        判断我这一行有没有k
            if(chars[x][i]=='0'+k)
                return false;
//        判断我这一列有没有k
            if(chars[i][y]=='0'+k)
                return false;
        }
//       判断九宫格内是否合法
        for (int i =(x/3)*3; i <((x/3)*3)+3; i++) {
            for (int j = (y/3)*3; j <((y/3)*3)+3; j++) {
                if(chars[i][j]=='0'+k)
                    return false;
            }
        }
        return true;
    }
}

测试样例:

030007004
602041000
050030967
040003006
087000350
900700020
718020040
000160809
400500030

总结

其实本算法灵魂的地方是x和y每次在递归中的增量的变化,也就是实现自动换行以及在check()中的检查九宫格是否合法。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值