AcWing 1613. 数独简单版

在这里插入图片描述
尽管说是数独简单版,可是对我来说却一点都不简单啊,这个很明显是用递归解决,这个递归又不同以往的递归,以往是一个节点为单位往下找,这个是一行为单位,从(0,0)到(9,9)顺序完全遍历一遍,我只涉及点为单位的递归,所以这个对我来说有点吃力,然后有引用了一个bool观察填这个节点是否可以填某个数。确实原理也很简单,把详细一点的写在注释上吧。

https://www.acwing.com/problem/content/1615/

代码如下

#include<iostream>
using namespace std;
char g[10][10];
int h[10][10],l[10][10],jg[3][3][10];//h行数字i是否被填上,l列数字i是否被填上,jg该九宫格是否填上i
bool dfs(int x,int y)
{
    
    
    if(y==9) x++,y=0;//默认一直向右遍历,然后遇到x出界自动调整
    if(x==9)//x已经完全遍历完了,输出结果并返回true结束程序
    {
    
    
        for(int i=0;i<9;i++)
        cout<<g[i]<<endl;
        return true;
    }
    if(g[x][y]!='.')//要是该点为一个数,就直接往右遍历
    return dfs(x,y+1);
    for(int i=1;i<=9;i++)//从数字1到9开始遍历看看能填什么数
    {
    
    
        if(!h[x][i]&&!l[i][y]&&!jg[x/3][y/3][i])//若是可以填
        {
    
    
            g[x][y]=i+'0';
            h[x][i]=l[i][y]=jg[x/3][y/3][i]=1;//这两行表示已经填上
            if(dfs(x,y+1)) return true;//要是可以就直接结束程序
            g[x][y]='.';//不可以进行一个还原然后重新去进行遍历
            h[x][i]=l[i][y]=jg[x/3][y/3][i]=0;
        }
    }
    return false;//若1-9都不行的话返回上一个节点。
}
int main(void)
{
    
    
    for(int i=0;i<9;i++) cin>>g[i];
    for(int i=0;i<9;i++)
    for(int j=0;j<9;j++)
    if(g[i][j]!='.')
    {
    
    
        h[i][g[i][j]-'0']=1;
        l[g[i][j]-'0'][j]=1;
        jg[i/3][j/3][g[i][j]-'0']=1;
    }//标记每个数字
    dfs(0,0);
}

猜你喜欢

转载自blog.csdn.net/qq_52358098/article/details/113573658