尽管说是数独简单版,可是对我来说却一点都不简单啊,这个很明显是用递归解决,这个递归又不同以往的递归,以往是一个节点为单位往下找,这个是一行为单位,从(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);
}