解题思路
这道题用搜索实现。
我们可以用三个数组 来标记行,列和九宫格里数字有没有填过。
然后模拟数字填写过程,把一到九全部考虑一次。
代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
int a[10][10],kj[10][10],lyx[10][10],bf[10][10][10];
bool flag;
string s;
int check(int x)//九宫格编号
{
if(x>=1&&x<=3)
return 1;
if(x>3&&x<=6)
return 2;
if(x>6&&x<=9)
return 3;
}
void dfs(int x,int y)
{
if(flag==1)
return;
if(x>9&&y==1)
{
for(int i=1; i<=9; i++)
for(int j=1; j<=9; j++)
printf("%d",a[i][j]);
printf("\n");
flag=1;
return;
}
if(a[x][y]!=0)//如果已有固定的数
{
if(y==9)
dfs(x+1,1);
else dfs(x,y+1);
return;
}
for(int i=1;i<=9;i++)
{
if(!kj[x][i]&&!lyx[y][i]&&!bf[check(x)][check(y)][i])//尝试填数
{
a[x][y]=i;
kj[x][i]=1;
lyx[y][i]=1;
bf[check(x)][check(y)][i]=1;
if(y==9)dfs(x+1,1);
else dfs(x,y+1);
a[x][y]=0;
kj[x][i]=0;
lyx[y][i]=0;
bf[check(x)][check(y)][i]=0;
}
}
}
int main()
{
while(cin>>s)
{
memset(a,0,sizeof(a));
memset(kj,0,sizeof(kj));
memset(lyx,0,sizeof(lyx));
memset(bf,0,sizeof(bf));
flag=0;
if(s=="end")
break;
for(int i=1; i<=9; i++)
{
for(int j=1; j<=9; j++)
{
if(s[(i-1)*9+j-1]>='1'&&s[(i-1)*9+j-1]<='9')
{
a[i][j]=s[(i-1)*9+j-1]-48;
kj[i][a[i][j]]=1;
lyx[j][a[i][j]]=1;
bf[check(i)][check(j)][a[i][j]]=1;//记录行、列、九宫格
}
}
}
dfs(1,1);
}
}