Java机试题*:数读(递归、回溯)

描述

问题描述:数独(Sudoku)是一款大众喜爱的数字逻辑游戏。玩家需要根据9X9盘面上的已知数字,推算出所有剩余空格的数字,并且满足每一行、每一列、每一个3X3粗线宫内的数字均含1-9,并且不重复。
例如:
输入
输出
 
数据范围:输入一个 9*9 的矩阵

输入描述:

包含已知数字的9X9盘面数组[空缺位以数字0表示]

输出描述:

完整的9X9盘面数组

复制代码
import java.util.Scanner;

/**
 * 
 * 思路:遍历矩阵,为0的位置,从1-9假设,首先判断假设后是否重复(满足每一行、每一列、每一个3X3粗线宫内的数字均含1-9,并且不重复。)
 * 若 没有重复,则按此假设的数递归判断是否能找到一个满足条件的结果,若没有找到则回溯为0,继续下一个假设值。
 *
 */
public class Main {

    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        while (in.hasNextInt()) {
            int[][] arr = new int[9][9];
            // 9 * 9 的矩阵
            for (int i = 0; i < arr.length; i++) {
                for (int j = 0; j < arr.length; j++) {
                    arr[i][j] = in.nextInt();
                }
            }
            // 遍历矩阵,利用条件(满足每一行、每一列、每一个3X3粗线宫内的数字均含1-9,并且不重复。)计算0位置对应的数字
            // 先填充可以明确的数字,不能判断的,等能确定的完成后,继续遍历知道全部确定完
            suDu(arr);
            for (int i = 0; i < arr.length; i++) {
                for (int j = 0; j < arr.length; j++) {
                    System.out.print(arr[i][j] + " ");
                }
                System.out.println();
            }            
        }
    }

    private static boolean suDu(int[][] arr) {
        for (int row = 0; row < arr.length; row++) {
            for (int col = 0; col < arr.length; col++) {
                if(arr[row][col] == 0) {
                    // 若有多个可能,则一个一个假设
                    for (int i = 0; i < arr.length; i++) {
                        int val = i + 1;
                        // 首先假设值,满足,行列宫不重复条件
                        if(!checkRepeat(row, col, val, arr)) {
                            arr[row][col] =  val;
                            // 并且该假设值,可以找到一组解
                            if(suDu(arr)) {
                                return true;
                            }
                            // 该假设值,没有找到,则回溯为0
                            arr[row][col] = 0;
                        };
                    }
                    // 若假设完,没有找到则,则返回false
                    return false;
                }
            }
        }
        return true;
    }
    
    public static boolean checkRepeat(int row, int col,int val, int[][] arr) {
        boolean ret = false; // 不重复
        // 行列已有的
        for (int k = 0; k < arr.length; k++) {
            if(arr[row][k] == val || arr[k][col] == val) {
                ret = true;
                break;
            }
        }
        int iBegain = (row / 3) * 3;
        int iEnd = iBegain + 3;
        int jBegain = (col / 3) * 3;;
        int jEnd = jBegain + 3;
        // 3x3矩阵范围中已有的
        for (int k = iBegain; k < iEnd; k++) {
            for (int k2 = jBegain; k2 < jEnd; k2++) {
                if(arr[k][k2] == val) {
                    ret = true;
                    break;
                }
            }
        }
        return ret;
    }
    
}
复制代码

题目来源:牛客网

参考链接:https://www.nowcoder.com/practice/78a1a4ebe8a34c93aac006c44f6bf8a1?tpId=37&&tqId=21267&rp=1&ru=/ta/huawei&qru=/ta/huawei/question-ranking

posted @   对月当歌  阅读(168)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示