数独
思路:用深搜来解决,可以从左往右,从上往下来搜,用三个二维数组来标记行列和3x3的方块已经出现过的数字,从1到9深搜,每次填写一个数的时候进行一次判断,如果不对,返回值为零。每次搜索的下面判断返回值,如果为1,说明之前的数字填的对,如果为0,说明之前的数字填的不对,要重新填。
hang[ i ][ j ] 表示 i 行的 j 是否出现
lie[ i ][ j ] 表示i列的j 是否出现过
ge[ i] [ j ] 表示 第i个格子 j 是否出现过
#include<stdio.h>
#include<string.h>
#include<iostream>
using namespace std;
int e[10][10],hang[10][10],lie[10][10],ge[10][10];
int yao(int i,int j)//判断格子
{
if(i>=1&&i<=3&&j>=1&&j<=3)
return 1;
if(i>=1 && i<=3 && j>=4 && j<=6)
return 2;
if(i>=1 && i<=3 && j>=7 && j<=9)
return 3;
if(i>=4 && i<=6 && j>=1 && j<=3)
return 4;
if(i>=4 && i<=6 && j>=4 && j<=6)
return 5;
if(i>=4 && i<=6 && j>=7 && j<=9)
return 6;
if(i>=7&&i<=9&& j>=1 && j<=3)
return 7;
if(i>=7&&i<=9&& j>=4 && j<=6)
return 8;
if(i>=7&&i<=9&& j>=7 && j<=9)
return 9;
}
int dfs(int x,int y)//从第一行往右搜
{
if(x==10)//搜索完毕
return 1;
int flag=0;//
if(e[x][y])//有值
{
if(y==9)
flag=dfs(x+1,1);//下一行
else flag=dfs(x,y+1);//下一列
if(flag)//-----//说明之前填的正确与否
return 1;
else return 0;//如果不正确 重新填 第55行
}
else
{
int k=yao(x,y);
for(int i=1; i<=9; i++)//列举 1 ~ 9
{
if(!hang[x][i]&&!lie[y][i]&&!ge[k][i])//不重复
{
e[x][y]=i;
hang[x][i]=1;
lie[y][i]=1;
ge[k][i]=1;
if(y==9)
flag=dfs(x+1,1);
else flag=dfs(x,y+1);//返回正确性
if(!flag)//不合法 重新填
{
e[x][y]=0;
hang[x][i]=0;
lie[y][i]=0;
ge[k][i]=0;
}
else return 1;//-------//说明之前填的正确
}
}
}
return 0;
}
int main()
{
int n;
scanf("%d",&n);
while(n--)
{
//getchar();
memset(e,0,sizeof(e));
memset(hang,0,sizeof(hang));
memset(lie,0,sizeof(lie));
memset(ge,0,sizeof(ge));
char c[12];
for(int i=1; i<=9; i++)
{
scanf("%s",c);
for(int j=1; j<=9; j++)
{
e[i][j]=c[j-1]-'0';
if(e[i][j])
{
hang[i][e[i][j]]=1;
lie[j][e[i][j]]=1;
int t1=yao(i,j);
ge[t1][e[i][j]]=1;
}
}
}
dfs(1,1);
for(int i=1; i<=9; i++)
{
for(int j=1; j<=9; j++)
printf("%d",e[i][j]);
printf("\n");
}
}
return 0;
}