m0_61574664 2022-01-14 19:00 采纳率: 87.1%
浏览 82
已结题

解数独,c++基础题,有几个问题

class Solution {
private:
bool line[9][9];
bool column[9][9];
bool block[3][3][9];
bool valid;
vector<pair<int, int>> spaces;

public:
void dfs(vector<vector>& board, int pos) {
if (pos == spaces.size()) {
valid = true;
return;
}

    auto [i, j] = spaces[pos];
    for (int digit = 0; digit < 9 && !valid; ++digit) {
        if (!line[i][digit] && !column[j][digit] && !block[i / 3][j / 3][digit]) {
            line[i][digit] = column[j][digit] = block[i / 3][j / 3][digit] = true;
            board[i][j] = digit + '0' + 1;
            dfs(board, pos + 1);
            line[i][digit] = column[j][digit] = block[i / 3][j / 3][digit] = false;
        }
    }
}

void solveSudoku(vector<vector<char>>& board) {
    memset(line, false, sizeof(line));
    memset(column, false, sizeof(column));
    memset(block, false, sizeof(block));
    valid = false;

    for (int i = 0; i < 9; ++i) {
        for (int j = 0; j < 9; ++j) {
            if (board[i][j] == '.') {
                spaces.emplace_back(i, j);
            }
            else {
                int digit = board[i][j] - '0' - 1;
                line[i][digit] = column[j][digit] = block[i / 3][j / 3][digit] = true;
            }
        }
    }

    dfs(board, 0);
}

};
这是力扣上的原题中的官方解答递归方法,来个负责任的大佬
问: spaces.emplace_back(i, j);他这是如何进行填充的呢,随机吗,如果是随机,,他这个数如果不合适怎么办,我全程都看不到筛选的函数啊。
问:valid = false;这个vaild起什么作用呢,我觉得有他没他不重要,是这样吗?
问:auto [i, j] = spaces[pos];这个代码涉及到的语法是什么呢,为什么不能写成 auto spacesi,j;呢
问: void dfs(vector<vector>& board, int pos)声明这个函数到底它的作用是什么呢? line[i][digit] = column[j][digit] = block[i / 3][j / 3][digit] = false;到最后不都应该会被判定成 line[i][digit] = column[j][digit] = block[i / 3][j / 3][digit] = true;吗?这看得我头晕。。。
来个负责任的大佬,希望能讲详细一点

  • 写回答

3条回答 默认 最新

  • 来把薯条 2022-01-14 22:17
    关注

    已添加详细的注释

    
    class Solution {
    private:
    
        // 分别标记每个单元格行,列,所属块内可以填写的数字
        bool line[9][9];    // 例:第一维表示共有九行,第二维标记该行可以填充的数字
        bool column[9][9];
        bool block[3][3][9];
        bool valid;     // 标记数独是否解出
        vector<pair<int, int>> spaces;  // 空缺位置的行列坐标
    
    public:
        void dfs(vector<vector<char>>& board, int pos) {
    
            // 如果空缺位置按照标记填充结束,结束搜索
            if (pos == spaces.size()) {
                valid = true;
                return;
            }
    
            // 取出第pos个空缺位置的坐标
            auto [i, j] = spaces[pos];
    
            // 如果数独还未求解出来,往空缺位置按0-9顺序填数
            for (int digit = 0; digit < 9 && !valid; ++digit) {
    
                // 如果这个数可以被填进去
                if (!line[i][digit] && !column[j][digit] && !block[i / 3][j / 3][digit]) {
    
                    // 将数标记
                    line[i][digit] = column[j][digit] = block[i / 3][j / 3][digit] = true;
    
                    // 将数填写到答案中
                    board[i][j] = digit + '0' + 1;
    
                    // 给下一个空缺处填写数字
                    dfs(board, pos + 1);
    
                    // 这个数可以填进去,但之后的数不能填进去,所以这个数不能填在这儿,则重新换个数填空
                    line[i][digit] = column[j][digit] = block[i / 3][j / 3][digit] = false;
                }
    
                // 如果不可以被填写进去,就换个数字填
            }
        }
    
        void solveSudoku(vector<vector<char>>& board) {
    
            // 将各标记置为默认值false
            memset(line, false, sizeof(line));
            memset(column, false, sizeof(column));
            memset(block, false, sizeof(block));
            valid = false;
    
            // 将各标记按照题中所给数据进行初始化
            for (int i = 0; i < 9; ++i) {
                for (int j = 0; j < 9; ++j) {
                    if (board[i][j] == '.') {
                        spaces.emplace_back(i, j);
                    }
                    else {
                        int digit = board[i][j] - '0' - 1;  // 数独中的数字
    
                        // 为各标记数组设置标记
                        line[i][digit] = column[j][digit] = block[i / 3][j / 3][digit] = true;
                    }
                }
            }
    
            // dfs来搜索存在的可行解,从第“0”个空缺位置开始
            dfs(board, 0);
        }
    };
    

    问: spaces.emplace_back(i, j);他这是如何进行填充的呢,随机吗,如果是随机,,他这个数如果不合适怎么办,我全程都看不到筛选的函数啊。
    space是动态数组,填充的是按行列顺序的空缺处的坐标,不是随机填充的。筛选的那步是dfs里面的判断。

    问:valid = false;这个vaild起什么作用呢,我觉得有他没他不重要,是这样吗?
    皮一下,我删了之后代码提交不通过,所以很重要。

    问:auto [i, j] = spaces[pos];这个代码涉及到的语法是什么呢,为什么不能写成 auto spacesi,j;呢
    C++的智能类型推断,后面的类型为pair<int,int>,所以等价于pair<int,int> [i, j]。因为这样写spacei和j都是pair<int,int>类型。

    问: void dfs(vector& board, int pos)声明这个函数到底它的作用是什么呢? line[i][digit] = column[j][digit] = block[i / 3][j / 3][digit] = false;到最后不都应该会被判定成 line[i][digit] = column[j][digit] = block[i / 3][j / 3][digit] = true;吗?这看得我头晕。。。
    来个负责任的大佬,希望能讲详细一点
    将第i行的digit标记为已填入,同理列和块。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?

问题事件

  • 系统已结题 1月23日
  • 已采纳回答 1月15日
  • 创建了问题 1月14日

悬赏问题

  • ¥15 用友U8:向一个无法连接的网络尝试了一个套接字操作,如何解决?
  • ¥30 我的代码按理说完成了模型的搭建、训练、验证测试等工作(标签-网络|关键词-变化检测)
  • ¥50 mac mini外接显示器 画质字体模糊
  • ¥15 TLS1.2协议通信解密
  • ¥40 图书信息管理系统程序编写
  • ¥20 Qcustomplot缩小曲线形状问题
  • ¥15 企业资源规划ERP沙盘模拟
  • ¥15 树莓派控制机械臂传输命令报错,显示摄像头不存在
  • ¥15 前端echarts坐标轴问题
  • ¥15 ad5933的I2C