又是一种有趣的dfs
读题我们可以知道:0上要填的数应该是该行、该列和方块(33)中都未出现的数字
这是我们机会想先做一个check函数,用来检查填的数是否合格
这里的难点是方块(33)如何判断,这就需要我们常用的数学,x本身减去x%3,结果就是它第一个数字。通过这种方式,我们可以确定(x,y)所在位置的方块的首地址
int check(int x,int y,int num)
{
for(int i=0;i<9;i++)
{
if(a[x][i]==num||a[i][y]==num)
return 0;
}
int xx,yy;
xx=x-x%3;
yy=y-y%3;
for(int i=xx;i<xx+3;i++)
for(int j=yy;j<yy+3;j++)
{
if(a[i][j]==num)
return 0;
}
return 1;
}
完整代码
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int a[10][10],n,dir[83][2];
int check(int x,int y,int num)
{
for(int i=0;i<9;i++)
{
if(a[x][i]==num||a[i][y]==num)
return 0;
}
int xx,yy;
xx=x-x%3;
yy=y-y%3;
for(int i=xx;i<xx+3;i++)
for(int j=yy;j<yy+3;j++)
{
if(a[i][j]==num)
return 0;
}
return 1;
}
int dfs(int shu)
{
if(shu<0)
return 1;
int x=dir[shu][0],y=dir[shu][1];
for(int k=1;k<=9;k++)
if(check(x,y,k))
{
a[x][y]=k;
if(dfs(shu-1)) return 1;
a[x][y]=0;
}
return 0;
}
int main()
{cin>>n;
while(n--) {
memset(dir,0,sizeof(dir));
memset(a,0,sizeof(a));
int shu=0;
for(int i=0;i<9;i++)
{ char c;
c=getchar();
for(int j=0;j<9;j++)
{
c=getchar();
a[i][j]=c-'0';
if(!a[i][j])
{
dir[shu][0]=i;//记录第记得0所在的x,y
dir[shu++][1]=j;
}
}
}
dfs(shu-1);
for(int i=0;i<9;i++)
{
for(int j=0;j<9;j++)
cout<<a[i][j];
cout<<endl;
}}
return 0;
}