数独简单版

数独是一种传统益智游戏,你需要把一个 9×99×9 的数独补充完整,使得图中每行、每列、每个 3×33×3 的九宫格内数字 1∼91∼9 均恰好出现一次。

请编写一个程序填写数独。

输入格式

输入共 99 行,每行包含一个长度为 99 的字符串,用来表示数独矩阵。

其中的每个字符都是 1∼91∼9 或 ..(表示尚未填充)。

输出格式

输出补全后的数独矩阵。

数据保证有唯一解。

输入样例:
.2738..1.
.1...6735
.......29
3.5692.8.
.........
.6.1745.3
64.......
9518...7.
.8..6534.
输出样例:
527389416
819426735
436751829
375692184
194538267
268174593
643217958
951843672
782965341

 本题目还是老套的搜索题目

其中行遍历,列遍历,以及九宫格遍历

行遍历代码:

for(int i=0;i<9;i++)

if(a[x][i]>47&&a[x][i]<58)//字符串检查1-9

st[a[x][i]^48]=true;

思路是什么呢,就是两个变量一个表示行一个表示列然后,固定一个,遍历一个,然后将开一个bool类型的数组如果当前位置以及数字,就把当前位数和数字都一并存入

九宫格遍历

int sx=x/3*3,sy=y/3*3;一个元素所在九宫格

什么这样计算?

  • 除以3:我们首先将行号或列号除以3,这是因为每个3x3的小方格在数独中占据3行和3列。
  • 乘以3:然后我们将得到的结果乘以3,这样可以将行号或列号调整回原来格子的起始行号或列号。

例子

假设我们有一个坐标 (x, y) = (3, 3)

  1. 对于行号 x

    • x / 3 = 3 / 3 = 1,这表示第3行是第2个3行组(从0开始计数)。
    • 1 * 3 = 3,这表示第2个3行组的起始行号是3。
  2. 对于列号 y

    • y / 3 = 3 / 3 = 1,这表示第3列是第2个3列组(从0开始计数)。
    • 1 * 3 = 3,这表示第2个3列组的起始列号是3。

因此,(x, y) = (3, 3) 所在的3x3九宫格的左上角坐标确实是 (2, 2),而不是 (3, 3)。这是因为 (2, 2) 是该九宫格的左上角顶点,而 (3, 3) 是该九宫格内的一点。

总结

  • sx = x / 3 * 3 计算的是当前行所在的3x3九宫格的起始行号。
  • sy = y / 3 * 3 计算的是当前列所在的3x3九宫格的起始列号。

这种计算方法适用于数独的任何位置,可以准确地找到任何单元格所在的3x3九宫格的左上角坐标。

行号: 0  1  2  3  4  5  6  7  8
列号:
0  1  2   3  4  5   6  7  8
0 +---+---+---+---+---+---+---+---+
1 +---+---+---+---+---+---+---+---+
2 +---+---+---+---+---+---+---+---+
3 +---+---+---+---+---+---+---+---+
4 +---+---+---+---+---+---+---+---+
5 +---+---+---+---+---+---+---+---+
6 +---+---+---+---+---+---+---+---+
7 +---+---+---+---+---+---+---+---+
8 +---+---+---+---+---+---+---+---+

 如果x=2,y=3那么sx=0,sy=3;满足

这个做法目的就是为了将初始坐标定在九宫格最上边的位置

接下来典型的九宫格遍历

int sx=x/3*3,sy=y/3*3;//这个步骤是把起始坐标为九宫格最左边的位置
    for(int i=sx;i<sx+3;i++)
        for(int j=sy;j<sy+3;j++)
          if (a[i][j] > 47 && a[i][j] < 58)
              st[a[x][i]^48] = true;

遍历完成之后就要进行所有情况预演,也就是搜索本体

for(int i=1;i<N;i++)
        if(!st[i]){//如果没走过
        a[x][y] = i^48;    //将有可能的数字存入
        if(dfs(x+1,y))return true;//表示当前位置进行一个判断能行的话就进行下一步遍历
        }        
    a[x][y] = '.';//回溯             

    return false;//如果尝试了所有可能的数字,都无法找到有效的解决方案,那么返回 false。  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值