首页 > 其他分享 >37. 解数独

37. 解数独

时间:2024-12-18 17:23:51浏览次数:6  
标签:int 37 vector board blk 解数 true row

  1. 题目链接

  2. 解题思路:整体思路是一个回溯,一行一行填。然后填的过程中可以剪枝,也就是我们可以添加一些约束条件,不能填的时候,就没必要去尝试了(还有一种填法,全部填完之后,再检查是否合规,这样复杂度太大了)。具体细节看代码。

  3. 代码

    class Solution {
    public:
        //   0~8行,0~8列,一行一行填
        // 现在来到i行,j列,row[x][y]是行限制,若为true,则说明第x行,y这个数字已经填过了
        // col[x][y]是列限制,若为true,则说明第x列,y这个数字已经填过了
        // blk[x][y]是块限制,若为true,则说明第x块,y这个数字已经填过了,对于[i,j]是 i / 3 * 3 + j / 3块
        bool process(vector<vector<char>>& board, int i, int j, vector<vector<bool>> &row, vector<vector<bool>> &col
        , vector<vector<bool>> &blk) {
            if (i == 9) {    // 全部填完了
                return true;
            }
            int nexti = j == 8? i + 1 : i;    // 下一个要填的行
            int nextj = j == 8 ? 0 : j + 1;   // 下一个要填的列
            if (board[i][j] != '.') {     // 如果不需要填,则填下一个位置
                
                return process(board, nexti, nextj, row, col, blk);
            }
            // 该位置需要填,填什么?循环遍历1~9
            for (int num = 1; num <= 9; ++num) {
                bool next = false;
                if (row[i][num] || col[j][num] || blk[i / 3 * 3 + j / 3][num]) {     // 不能填
                    continue;
                }
                // 目前可以填
                board[i][j] = num + '0';
                // 添加约束
                row[i][num] = true;
                col[j][num] = true;
                blk[i / 3 * 3 + j / 3][num] = true;
                next = process(board, nexti, nextj, row, col, blk);
                if (next) {    // 如果填好了  直接返回了
                    return true;
                }
                board[i][j] = '.';     // 恢复现场
                row[i][num] = false;
                col[j][num] = false;
                blk[i / 3 * 3 + j / 3][num] = false;
            }
            // 都没有满足
            return false;
    
        }
    
        void solveSudoku(vector<vector<char>>& board) {
        
            vector<vector<bool>> row(9, vector<bool>(10, false));
            vector<vector<bool>> col(9, vector<bool>(10, false));
            vector<vector<bool>> blk(9, vector<bool>(10, false));
            // 添加约束
            for (int i = 0; i < 9; ++i) {
                for (int j = 0; j < 9; ++j) {
                    if (board[i][j] == '.') {
                        continue;
                    }
                    row[i][board[i][j] - '0'] = true;
                    col[j][board[i][j] - '0'] = true;
                    blk[i / 3 * 3 + j / 3][board[i][j] - '0'] = true;
                }
            }
            process(board, 0, 0, row, col, blk);
        }
    };
    

标签:int,37,vector,board,blk,解数,true,row
From: https://www.cnblogs.com/ouyangxx/p/18615439

相关文章

  • 彻底理解数据库何时需要分表问题
    在阿里巴巴开发手册中写道:【推荐】单表行数超过500万行或者单表容量超过2GB,才推荐进行分库分表。说明:如果预计三年后的数据量根本达不到这个级别,请不要在创建表时就分库分表。大家在网上肯定看到过很多关于分库分表的情况,很多说到当数据量达到2000W行的时候就需要分库分......
  • 浙江工商大学 ZJGSU OJ 2037. 个人信息管理系统
    目录题面思路重点代码题面2037.个人信息管理系统描述小张是同学会的负责人,但是复杂的联系信息让他很头痛,请你帮他写一个个人信箱的管理系统(人数小于30人),每个人包含3项信息:姓名(小于20个字符) 性别(Female=女,Male=男) 生日(年月日)每个人用一个结构体表示,......
  • (8)CT137A- 三八译码器设计
    (1)实现代码:moduledecoder3_8( input wire key_en , input wire A , //S0 input wire B , //S1 input wire C , //S2 output reg [7:0] led_out );//观察原理图,可知该开发板的按键按下电平为0,释放电平为1//该开发板电平为1时le......
  • 题解:P11372 「CZOI-R2」加训
    暴力三重循环,枚举学生,障碍和老师,再判断是否合法。时间复杂度:\(\Theta(mxy)\)。但是会TLE。暴力优化用数组\(oier\)来存储二元组\((x,y)\)对应的坐标\(z\)。这样就省去的开三维数组的成本。然后只用枚举学生和老师,再判断维度坐标不同数是否为\(k-1\)个,以及中间有没......
  • P11378[GESP202412 七级]燃烧 题解
    闲话花了一个小时。主要原因:条初始值硬控我半小时,题目看错硬控我半小时(悲)。正文看题目,就是求从哪个点出发所得到的所有单调下降序列的总长度最长(这个描述好奇怪,不过意思是对的)。题目中说的是树,但其实可以当做图来做,因为题目中提到的是“节点”,而与父亲儿子节点无关,也就是说儿......
  • Axure RP 9.0.0.3727 免费版安装使用教程
    Axurerp是美国Axuresoftwaresolution公司的旗舰产品。它是一种专业的快速原型设计工具,允许负责定义需求和规格、设计功能和界面的专家快速创建应用软件或web网站的线框图、流程图、原型和规格描述文档。作为一种专业的原型设计工具,它可以快速高效地创建原型,同时支持多人合作设......
  • 科丁乐K12137 二叉树中的秘密
    题目描述新年伊始,我飞买了一棵二叉树,传闻这棵二叉树的某一个节点上隐藏着上古的秘密,于是我飞开始昼夜不息的寻找。本着不遗漏任何一个节点的原则,飞神打算遍历整棵二叉树。设S为飞神当前所处的节点。若S有两个子节点L,R,则飞神总是先去遍历节点较少的那棵子树,然后再去遍历另......
  • P10370 「LAOI-4」Mex Tower (Hard ver.) 题解
    有一定难度的思维题。题目传送门思路首先,\(\operatorname{mex}(x,y)\)的结果一定为\(0,1,2\),因为只有两个数,所以结果最多为\(2\)(\(x=1,y=0\)或\(x=0,y=1\)时)。因此,可以将问题转化为最后的数是否为\(2\)。考虑倒推,当\(n=1\)时,显然只能为\(2\);要从\(n=2\)的情况变为......
  • VS下进行CUDA编译时error MSB3721相关的原因之一
    报错:“1>D:\MicrosoftVisualStudio\2019\Community\MSBuild\Microsoft\VC\v160\BuildCustomizations\CUDA11.6.targets(790,9):errorMSB3721:命令“"C:\ProgramFiles\NVIDIAGPUComputingToolkit\CUDA\v11.6\bin\nvcc.exe"-gencode=arch=com......
  • 【日记】被舞房的孩子送了一颗泡泡糖(1437 字)
    正文拖延症好严重,这就是爆炸忙完之后的后遗症吗……五支钢笔墨水都用完了。但有些烦躁,不想去打墨水,所以这则日记是用佳芯小姐买的签字笔写的。说实话,我觉得她买的这根笔不是很好用……不过算是笔袋里最好用的一支了,比起培训送的笔还是要好上许多。只是三角状的笔杆有些硌人......