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

news2025/2/25 5:44:49

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

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();
        }
    }
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

pycharm学生认证免费使用专业版

进入pycharm官网Monthly and yearly plans with JetBrains Toolboxhttps://www.jetbrains.com/store/?fromMenu#discounts ​​​ 按照要求填写&#xff0c;但是如果遇到这个提示&#xff0c;恭喜你&#xff0c;你的学校获得了美国商务部认证。 ​ 遇到这个不要慌&#…

Spring Boot - Application Events 的发布顺序_ApplicationStartingEvent

文章目录 概述Code源码分析 概述 Spring Boot 的广播机制是基于观察者模式实现的&#xff0c;它允许在 Spring 应用程序中发布和监听事件。这种机制的主要目的是为了实现解耦&#xff0c;使得应用程序中的不同组件可以独立地改变和复用逻辑&#xff0c;而无需直接进行通信。 …

残差网络 ResNet

目录 1.1 ResNet 2.代码实现 1.1 ResNet 如上图函数的大小代表函数的复杂程度&#xff0c;星星代表最优解&#xff0c;可见加了更多层之后的预测比小模型的预测离真实最优解更远了&#xff0c; ResNet做的事情就是使得模型加深一定会使效果变好而不是变差。 2.代码实现 impo…

java版微信小程序商城 免 费 搭 建 java版直播商城平台规划及常见的营销模式有哪些?电商源码/小程序/三级分销

涉及平台 平台管理、商家端&#xff08;PC端、手机端&#xff09;、买家平台&#xff08;H5/公众号、小程序、APP端&#xff08;IOS/Android&#xff09;、微服务平台&#xff08;业务服务&#xff09; 2. 核心架构 Spring Cloud、Spring Boot、Mybatis、Redis …

用通俗易懂的方式讲解:使用 LlamaIndex 和 Eleasticsearch 进行大模型 RAG 检索增强生成

检索增强生成&#xff08;Retrieval-Augmented Generation&#xff0c;RAG&#xff09;是一种结合了检索&#xff08;Retrieval&#xff09;和生成&#xff08;Generation&#xff09;的技术&#xff0c;它有效地解决了大语言模型&#xff08;LLM&#xff09;的一些问题&#x…

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

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

企业为什么要选择软件定制开发?

引言&#xff1a;定制开发的兴起 在商业竞争日益激烈的今天&#xff0c;企业领导者们面临着一个重要的抉择&#xff1a;是选择通用软件解决方案&#xff0c;还是探寻更贴合企业需求的定制开发路径&#xff1f; 在企业决策软件解决方案时&#xff0c;通用软件和软件定制开发各…

IOS-高德地图连续定位-Swift

使用定位功能需要需要接入高德地图定位Api&#xff1a; pod AMapLocation配置Info 在info中新建一个名为Privacy - Location Temporary Usage Description Dictionary的字典&#xff0c;然后在这个字典下新建Privacy - Location When In Use Usage Description、Privacy - Lo…

应用案例 | Softing工业物联网连接解决方案助力汽车零部件供应商实现智能制造升级

随着业务的扩展和技术的进步&#xff0c;某国际先进汽车零部件供应商在其工业物联网的升级方案中使用了Softing的dataFEED OPC Suite——通过MQTT协议将现场控制器和数控系统的数据上传到其物联网云平台&#xff0c;从而实现了设备状态的远程监控&#xff0c;不仅能够提前发现设…

drools开源规则引擎介绍以及在Centos上的具体部署方案,让你的业务规则能够独立于应用程序本身

Drools是一个基于Java的开源规则引擎&#xff0c;用于处理业务规则和复杂事件处理。它提供了一个声明性的规则语言&#xff0c;允许开发人员定义业务规则&#xff0c;并通过引擎执行这些规则。以下是Drools规则引擎的简介和一些应用场景描述。 Drools规则引擎简介 规则引擎概述…

消费增值模式:引领消费者与平台共创双赢的新篇章

在数字化时代&#xff0c;消费模式正在发生深刻变革。消费者不再满足于单纯的购物行为&#xff0c;而是寻求更加个性化和有价值的消费体验。而平台也面临着如何吸引和留住消费者的挑战。消费增值模式作为一种新型的商业模式&#xff0c;正逐渐成为解决这一问题的关键。 消费增…

钢岚芯片:如何获取及鉴别真伪?

在不断变革的高科技时代&#xff0c;芯片技术作为科技前沿的重要标志&#xff0c;已成为衡量一个国家和地区科技实力的重要指标。钢岚芯片&#xff0c;这一神秘而又先进的科技产物&#xff0c;作为当前芯片科技研究的巅峰之作&#xff0c;吸引了无数科技爱好者和业界精英的追捧…

ROS第 6 课 编写简单的订阅器 Subscriber

文章目录 第 6 课 编写简单的订阅器 Subscriber1. 编写订阅者节点2. 测试发布者和订阅者 第 6 课 编写简单的订阅器 Subscriber 订阅器是基于编辑了发布器的基础上创建的&#xff0c;只有发布了消息&#xff0c;才有可能订阅。若未编辑发布器&#xff0c;可前往"ROS第5课 …

SQL注入漏洞的检测及防御,零基础入门到精通

SQL注入&#xff08;SQL Injection&#xff09;是一种广泛存在于Web应用程序中的严重安全漏洞&#xff0c;它允许攻击者在不得到授权的情况下访问、修改或删除数据库中的数据。这是一种常见的攻击方式&#xff0c;因此数据库开发者、Web开发者和安全专业人员需要了解它&#xf…

WordPress后台仪表盘自定义添加删除概览项目插件Glance That

成功搭建WordPress站点&#xff0c;登录后台后可以在“仪表盘 – 概览”中看到包括多少篇文章、多少个页面、多少条评论和当前WordPress版本号及所使用的主题。具体如下图所示&#xff1a; 但是如果我们的WordPress站点还有自定义文章类型&#xff0c;也想在概览中显示出来应该…

OpenLayers实战,OpenLayers点聚合有相同经纬度坐标时无法展开问题解决办法,当缩放级别达到一定等级后强行展开聚合为单个点

专栏目录: OpenLayers实战进阶专栏目录 前言 本章用于解决OpenLayers使用Cluster点聚合情况下,要素(Feature)出现有相同经纬度坐标时无法展开成单独图标的问题解决办法以及当缩放级别达到一定等级后强行展开聚合为单个点的功能。 本章展开后由于经纬度坐标还是同一个点,…

Spring Security- 基于角色的访问控制

基于角色 或权限 进行访问控制 hasAuthority方法 如果当前的主体具有指定的权限,则返回true,否则返回false 修改配置类 //当前登录用户 只有具备admins权限才可以访问这个路径.antMatchers("/test/index").hasAuthority("admins") 代码如下: package c…

【面试合集】说说微信小程序的发布流程?

面试官&#xff1a;说说微信小程序的发布流程&#xff1f; 一、背景 在中大型的公司里&#xff0c;人员的分工非常仔细&#xff0c;一般会有不同岗位角色的员工同时参与同一个小程序项目。为此&#xff0c;小程序平台设计了不同的权限管理使得项目管理者可以更加高效管理整个团…

vue3-模板引用

//1.调用ref函数 -> ref对象 const h1Ref ref(null) const comRef ref(null) //组件挂载完毕之后才能获取 onMounted(()>{console.log(h1Ref.value);console.log(comRef.value); })<div class"father"><!-- 通过ref标识绑定ref对象 --><h2 re…

Apache Zeppelin学习记录2

Apache Zeppelin学习记录2 文章目录 Apache Zeppelin学习记录2前言一、基础调用二、带参数调用1.代码块要增加一行z.textbox("folder_path", "input")2.读取result 总结 前言 上一章讲了如何使用zeppelin来接入python&#xff0c;本节我们来看看如何使用R…