搜索经典题——填充 9*9矩阵

题目:给定一个九行九列矩阵,填充矩阵元素,要求:

1、每一行每一列,每个小九宫格(图片画粗的地方就是)不能包含相同元素

2、每一行,每一列,每个小九宫格均会完整出现1-9的数字

思路:DFS回溯填充数字,一行一行填充,当填充到第十行说明填充成功,每填充一个位置,都需要用"istrue"函数验证一下该位置是否合法(需要判断每一行,每一列,每个小九宫格是否包含了相同元素,唯一难点就是判断当前填充位置的小九宫格起点位置)  

//分治回溯 回溯的应用 之 数独问题
/*
判断填入的数据是否满足条件 一行中没有相同的 并且 一列中没有相同的 并且 当前方格所在的子方块中没有相同的
虽然数独问题只有一个解 但是我们解决数独问题时 是向多个解的方向去求解的
 */
public class SudoKu {
    //表示第count个解
    private static int count = 0;
    //表示存放数独数据的矩阵容器
    private static int[][] board= new int[9][9];
 
    public static void main(String[] args) throws IOException {
        readFile("SudoKu_data"); //读取数独文件
        solve(0, 0); //向数独矩阵中添加元素
    }
 
    //向数独矩阵中添加元素
    /*
    向下一个位置递归的 列的更新为:col=(col+1)%9
    行的更新:更新行必须将col递归到当前行的末尾时才能更新 更新为:row=row+(col+1)/9
    先判断递归临界条件 当行row递归到9时 则表示已经出现了一个解了
    否则判断指定位置(row,col)是否已经有数字了
    如果已经有数字了 直接跳过当前位置 向下一个位置继续递归即可
    否则 循环数字1-9 判断指定位置能够填入的数字(1-9中的哪个数字) 将其填入
    再向下一个位置继续递归即可
    当一种填法行不通时 必须要将当前位置填入的数字清空后 再向上回溯
     */
    private static void solve(int row, int col) {
        if(row == 9){ //判断递归临界条件
            count++;
            System.out.println("第" + count + "个解");
            printBoard();
        }else{
            //如果当前位置没有数字
            if(board[row][col] == 0){
                //就要填入1-9中满足条件的数字
                for(int num = 1; num <= 9; num++){
                    //判断当前位置要填入的数字 是否满足条件
                    /*条件:一行中没有与要填入的数字num相同的 并且 一列中没有与要填入的数字num相同的
                    并且 当前方格所在的子方块中没有与要填入的数字num相同的
                     */
                    if(!isExist(row, col, num)){
                        //将满足条件的数字填入到指定位置
                        board[row][col] = num;
                        //向下递归 解决下一个格子
                        solve(row + (col + 1) / 9, (col + 1) % 9);
                    }
                    board[row][col] = 0; //如果此处没解 必须清零此处的数字
                }
            }else{
                //已经存在一个已知数字 直接跳过去解决下一个格子
                solve(row + (col + 1) / 9, (col + 1) % 9);
            }
        }
    }
 
    /*判断当前位置要填入的数字 是否满足条件 如果指定范围中包含要添加的数字 则返回true
    若没有包含 表示可以将数字添加到指定方格中 返回false
     */
    private static boolean isExist(int row, int col, int num) {
        //同一行中是否包含指定元素num
        for(int c = 0; c < 9; c++){
            if(board[row][c] == num){
                return true;
            }
        }
        //同一列中是否包含指定元素num
        for(int r = 0; r < 9; r++){
            if(board[r][col] == num){
                return true;
            }
        }
 
        //在子方格(九宫格)中是否包含指定元素num 若总共是9*9 则就有九个3*3的子方格
        int rowMin = 0; //子方格中最小行的编号,默认值为0
        int colMin = 0; //子方格中最小列的编号,默认值为0
 
        int rowMax = 0; //子方格中最大行的编号,默认值为0
        int colMax = 0; //子方格中最大列的编号,默认值为0
 
        //设置子方格中的最小行,最小列,最大行,最大列的值 即子方格的行 列范围
        if(row >= 0 && row <= 2){
            rowMin = 0;
            rowMax = 2;
        }
        if(row >= 3 && row <= 5){
            rowMin = 3;
            rowMax = 5;
        }
        if(row >= 6 && row <= 8){
            rowMin = 6;
            rowMax = 8;
        }
        if(col >= 0 && col <= 2){
            colMin = 0;
            colMax = 2;
        }
        if(col >= 3 && col <= 5){
            colMin = 3;
            colMax = 5;
        }
        if(col >= 6 && col <= 8){
            colMin = 6;
            colMax = 8;
        }
 
        //遍历子方格 判断其中是否包含指定元素num
        for(int r = rowMin; r <= rowMax; r++){
            for(int c = colMin; c < colMax; c++){
                if(board[r][c] == num){
                    return true;
                }
            }
        }
        //若以上条件都不满足 则返回false 表示指定位置可以填入数字
        return false;
    }
 
    //读取文件中的数独矩阵
    private static void readFile(String fileName) throws IOException {
        File file = new File(fileName);
        FileReader fr = new FileReader(file);
        BufferedReader br = new BufferedReader(fr);
        int row = 0;
        String line = null;
        while ((line = br.readLine()) != null){
            for(int col = 0; col < line.length(); col++){
                board[row][col] = Integer.parseInt(line.charAt(col) + "");
            }
            row++;
        }
    }
 
    //打印数独矩阵
    private static void printBoard() {
        for(int i = 0; i < 9; i++){
            for(int j = 0; j < 9; j++){
                System.out.print(board[i][j] + " ");
            }
            System.out.println();
        }
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/328407.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Python进程池multiprocessing.Pool

环境&#xff1a; 鲲鹏920:192核心 内存&#xff1a;756G python&#xff1a;3.9 python单进程的耗时 在做单纯的cpu计算的场景&#xff0c;使用单进程核多进程的耗时做如下测试&#xff1a; 单进程情况下cpu的占用了如下&#xff0c;占用一半的核心数&#xff1a; 每一步…

第二百六十九回

文章目录 概念介绍设置方法示例代码内容总结 我们在上一章回中介绍了Card Widget相关的内容&#xff0c;本章回中将介绍国际化设置.闲话休提&#xff0c;让我们一起Talk Flutter吧。 概念介绍 我们在这里说的国际化设置是指在App设置相关操作&#xff0c;这样可以让不同国家的…

SAP PI之Rest adapter

一&#xff0c;简介 REST风格接口是以http为传输协议&#xff0c;以xml或json或text为有效负载。下图展示了REST到XI再返回的一个过程&#xff0c;一个REST接口包含的信息有&#xff1a;服务URL、URL中带的参数、http方法(post/get/put等)、http头部、body部分的有效载荷。而X…

2023年全球软件质量效能大会(QECon北京站):核心内容与学习收获(附大会核心PPT下载)

此次大会的主题为“智能时代的质量新篇章”。来自全球的软件质量与效能专家、企业领袖、技术研发人员等齐聚一堂&#xff0c;共同探讨软件质量与效能的新理念、新技术、新实践。 一、大会的核心内容 1、智能时代软件质量的新挑战与机遇 随着人工智能、大数据等技术的快速发展…

react、Vue打包直接运行index.html不空白方法

react vue 在根目录下创建 vue.config.js 文件&#xff0c;写入 module.exports {publicPath: ./, }

【SpringCloud】这一次终于使用MQ解决了Eureka服务下线延迟感知问题

前言 其实&#xff0c;“通过Redis手动更新Ribbon缓存来解决Eureka微服务架构中服务下线感知的问题”是一种解&#xff0c;但不是最优解 1.痛点 上一篇文章的标题是&#xff1a; 通过Redis手动更新Ribbon缓存来解决Eureka微服务架构中服务下线感知的问题 当时在文章的末尾就…

matlab 直道转向时方向盘最小转角算法

1、内容简介 略 33-可以交流、咨询、答疑 2、内容说明 汽车主动转向&#xff0c;直道转向时方向盘最小转角算法&#xff0c;一个m脚本和simulink的计算结果 略 3、仿真分析 略 4、参考论文 汽车主动转向关键技术研究

黑马程序员_多线程

基础知识 什么是线程 被包含在进程之中&#xff0c; 可以调度的最小单位应用软件中互相独立&#xff0c;可以同时运行的功能 什么是进程 程序的基本执行实体 总结&#xff1a; 什么是多线程&#xff1f; 有了多线程&#xff0c;可以让程序同时做多件事情 多线程有什么作用&…

DC电源模块在新能源领域的应用前景

BOSHIDA DC电源模块在新能源领域的应用前景 DC电源模块在新能源领域有着广阔的应用前景。随着可再生能源技术的发展和普及&#xff0c;如太阳能和风能等的应用逐渐增多&#xff0c;DC电源模块在这些领域的应用越来越重要。 首先&#xff0c;DC电源模块可以用于太阳能发电系统…

车载音频EMI的产生及典型音频功放AW836XX的解决方案

之前针对 eCall的文章中有提到D类音频功放需要关注EMI问题&#xff08;点击文章回看《车载eCall系统音频应用解决方案》&#xff09;&#xff0c;在此展开此问题并寻求解决方案。 1. EMI定义与分类 电磁干扰&#xff08;Electromagnetic Interference&#xff0c;EMI&#xff…

geemap学习笔记049:下载Landsat数据时遇到的一个问题

前言 最近在下载Landsat 8 地面反射率数据&#xff08;Surface Reflectance&#xff09;时&#xff0c;遇到了一个问题&#xff0c;无论是使用geemap.ee_export_image_to_drive() 函数还是geemap.download_ee_image() 函数下载的数据&#xff0c;易康都打不开&#xff0c;显示…

【CSDN博客系列】自定义模块

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

还在为crontab表达式发愁吗,快使用这个工具

是不是每次要定义cron表达式的时候&#xff0c;都去百度翻找资料&#xff0c;cron表达式难写难记真是苦天下程序员久已。有没有什么不拥记的办法就轻松掌握呢&#xff1f;最近发现这个CrontabGuru神器&#xff0c;强烈推荐&#xff0c;真是广大程序员的福音了。 简介 Crontab…

电脑技巧:安装手机与Win10电脑怎样互传文件,看完你就会了

目录 一、Windows网络邻居功能 二、数据线传输 三、蓝牙连接 大家在日常工作当中&#xff0c;会遇到需要实现手机和Win10电脑之间的文件传输&#xff0c;今天小编给大家推荐使用Win10系统自带的网络邻居功能来实现手机与电脑之间数据的传输&#xff0c;希望对大家日常办公提…

喜讯!无垠智能模糊测试系统入选“2023软件供应链优秀成果”

近日&#xff0c;中国信通院信息通信软件供应链安全社区正式公布了“2023软件供应链优秀成果”&#xff0c;其中&#xff0c;云起无垠的无垠智能模糊测试系统凭借其自主研发的创新成果&#xff0c;成功入选该名单。 图 获奖成果 自发起以来&#xff0c;软件供应链优秀成果案例…

html画动态桃心

html画动态桃心 效果图&#xff1a; 代码&#xff1a; <!DOCTYPE html> <html><head><meta http-equiv"Content-Type" content"text/html; charsetwindows-1252"><title></title><style>* {padding: 0;margin…

从uptime看linux平均负载

从前遇到系统卡顿只会top。。top看不出来怎么搞呢&#xff1f; Linux系统提供了丰富的命令行工具&#xff0c;以帮助用户和系统管理员监控和分析系统性能。在这些工具中&#xff0c;uptime、mpstat和pidstat是非常有用的命令&#xff0c;它们可以帮助你理解系统的平均负载以及资…

电子行业除镍树脂深度出水0.02ppm

项目名称 电子行业贴片电容废水除镍项目 工艺选择 两级串联运行 工艺原理 亚氨基二乙酸和重金属离子通过螯合作用形成稳定的配位键&#xff0c;实现选择性吸附重金属 项目背景 贴片电容&#xff0c;也被称为多层片式陶瓷电容器&#xff08;MLCC&#xff09;&#xff0c;…

SQL Server Management Studio创建数据表

文章目录 一、建表注意事项1.1 数据类型1.2 建立数据表的基本SQL语法 二、实例说明2.1 创建数据表2.2 实例2 三、标识列和主键示例&#xff1a; 一、建表注意事项 1.1 数据类型 可以看这个去了解数据类型&#xff1a; 1.2 建立数据表的基本SQL语法 建立数据表的基本 SQL 语…

UDS诊断(ISO14229-1) 36服务

文章目录 功能简介应用场景请求和响应1、请求2、子功能3、肯定响应4、否定响应 NRC 判断优先级顺序报文示例1、下载数据到服务器 UDS中常用 NRC 功能简介 36服务&#xff0c;即 TransferData&#xff08;传输数据&#xff09;服务&#xff0c;客户端利用 TransferData&#xf…