【20221119】【每日一题】解数独

编写一个程序,通过填充空格来解决数独问题。

数独的解法需 遵循如下规则:

数字 1-9 在每一行只能出现一次。
数字 1-9 在每一列只能出现一次。
数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。(请参考示例图)
数独部分空格内已填入了数字,空白格用 '.' 表示。


思路:1、题目中提到只有一个符合条件的结果,也就是说一旦找到符合的就返回,无需遍历完整个树,用bool作为返回值;

           2、3*3的格子依据是将9*9划分成9块区域;

           3、不需要写终止条件的原因我觉得是对于这块9*9的区域,已经用i,j的方法去遍历了,找完了都不符合就false,找到符合的就return true,如果9*9的格子遍历完了也没有返回false,于是返回true。

class Solution {
public:
    bool isValid(int row,int col,char k,vector<vector<char>>& board){
        //检验行是否符合规则
        for(int i=0;i<9;i++)
        {
            if(board[row][i]==k)    return false;
        }
        //检验列是否符合规则
        for(int i=0;i<9;i++)
        {
            if(board[i][col]==k)    return false;
        }
        //检验3*3宫内是否符合规则
        //将这个9*9的board划分成9个3*3的
        int x=row/3,y=col/3;
        for(int i=x*3;i<x*3+3;i++)
        {
            for(int j=y*3;j<y*3+3;j++)
            {
                if(board[i][j]==k)  return false;
            }
        }
        return true;
    }

    bool backtracking(vector<vector<char>>& board){
        //终止条件 不需要的原因是找不到'.'自然就结束了
        //处理 对这个9*9的空间处理
        for(int i=0;i<9;i++)
        {
            for(int j=0;j<9;j++)
            {   
                if(board[i][j]=='.')
                {
                    for(char k='1';k<='9';k++)
                    {
                        if(isValid(i,j,k,board))
                        {
                            board[i][j]=k;
                            if(backtracking(board)) return true;
                            board[i][j]='.';
                        }
                    }
                    return false;
                }
            }
        }
        //9*9的格子遍历完了也没有返回false,于是返回true
        return true;
    }
    void solveSudoku(vector<vector<char>>& board) {
        backtracking(board);
    }
};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
数独算法说明:用三个二维数组记录数独每个点的状态,SD(i, j)显示数值,也是真实数值(1到9)。ST(i, j)状态,1可由用户输入,2是题目给定的,不能改。SY(i, j)这符串,记录每个点中可能的值。 1、在进行自动计算时,只计算ST(i, j)为1的点,首先将所有状态为1的点的SY(i, j)值全部设为"123456789",SD(i, j)值全部设为0 2、逐点扫描,找到一个点,然后将该点所在的行、列、区域中已存在的SD(x, y)值从SY(i, j)中删除,因为数独规则是一个数值,在行、列、区域都不重复。 3、经第二步处理后,SY(i, j)为空,说明题目错误,SY(i, j)值为一位数字,就说明该点的值是唯一的,可以确定了。 4、剩余的SY(i, j)值最少也是二个数字的,或更多位数。随机从这些两位数的SY(i, j)中选取一个点。取其中的一位确定为该点的值后,重复第2步。如果错误遇错,则重复执行第4步。直到所有点都被确定。 注意:第2步是需要多次重复执行的,所有可用递归函数完成。如果执行结果出现错误(某数出现重复,或某点无值),需要对该过程所执行的所有操作进行回退。 第4步也是需要重复执行的。本和序用Goto跳转方式实现多次执行。 简单的数独,要么所有的点都具有独一值,第1步执行完成后,就已全部完成。或者具有多个,随意猜测一个二位数的SY(i, j)的值都能成功。 难的数独,是可唯一确定的点很少,大部分点都有两种或多种可能的值,但最终正确答案只有一种或很少种。 软件在自动计算过程中,具有很大的偶然性,对于骨灰级的数独题目在计算过程中,时间短的可能不到1秒就能完成,长的可能要几分钟,需要将各种可能性都测试一遍才有结果。 只要题目正确,多计算几次就能得到答案。 程序只处理有两种可能值的情况,对只存在三种可能值的情况未进一步处理,该情况非常极端了。 软件中包含网上下载的200个数独题目。
好的,我可以为您提供一个基于Python的数独程序,您可以使用以下代码: ```python def isValid(board, row, col, num): # Check row for i in range(9): if board[row][i] == num: return False # Check column for i in range(9): if board[i][col] == num: return False # Check square startRow = (row // 3) * 3 startCol = (col // 3) * 3 for i in range(startRow, startRow + 3): for j in range(startCol, startCol + 3): if board[i][j] == num: return False return True def solveSudoku(board): for row in range(9): for col in range(9): if board[row][col] == '.': for num in range(1, 10): if isValid(board, row, col, str(num)): board[row][col] = str(num) if solveSudoku(board): return True board[row][col] = '.' return False return True ``` 这个程序使用了回溯算法数独问题。它通过逐个尝试填充每个空单元格,如果填充的数值有效,则继续填充下一个单元格。如果无法填充,则执行回溯并尝试另一个值。最终,当所有单元格都填满时,数独得以决。 运行程序的方式是,使用一个9x9的矩阵来表示数独游戏的初始状态。空单元格应该表示为一个点“.”。例如,以下代码将数独谜题输入程序中并得到决方案: ```python board = [ ["5","3",".",".","7",".",".",".","."], ["6",".",".","1","9","5",".",".","."], [".","9","8",".",".",".",".","6","."], ["8",".",".",".","6",".",".",".","3"], ["4",".",".","8",".","3",".",".","1"], ["7",".",".",".","2",".",".",".","6"], [".","6",".",".",".",".","2","8","."], [".",".",".","4","1","9",".",".","5"], [".",".",".",".","8",".",".","7","9"] ] solveSudoku(board) for row in board: print(row) ``` 您可以将此代码复制并运行,并将其适当调整来决您的数独问题。希望能帮到您!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值