这个是我之前写过的一个DFS解数独的代码。记录数独的xzy三轴的状态来进行改变。写的比较垃圾,由于我当时没看出来九宫格关于xy两个轴的规律,所以还专门暴力写了一个函数来判断要怎么处理这个东西。
#include<stdio.h>
#include<algorithm>
#include<string.h>
bool visx[155][155];///记录xyz上状态
bool visy[155][155];
bool visz[155][155];
char Mapold[155][155];
int Map[155][155];
int flag = 0;
void z(int x,int y,int num,int gao)///改变z轴状态的
{
if(x <= 3 && y <= 3)
{
if(gao)
visz[1][num] = 1;
else
visz[1][num] = 0;
}
else if(x > 3 && x <= 6 && y <= 3)
{
if(gao)
visz[2][num] = 1;
else
visz[2][num] = 0;
}
else if(x > 6 && x <= 9 && y<= 3)
{
if(gao)
visz[3][num] = 1;
else
visz[3][num] = 0;
}
else if(x <= 3 && y > 3 && y<= 6)
{
if(gao)
visz[4][num] = 1;
else
visz[4][num] = 0;
}
else if( x <= 3 && y > 6 && y<=9)
{
if(gao)
visz[7][num] = 1;
else
visz[7][num] = 0;
}
else if(x > 3 && x <= 6 && y > 3 && y<=6)
{
if(gao)
visz[5][num] = 1;
else
visz[5][num] = 0;
}
else if(x > 6 && x <= 9 && y> 3 && y <= 6)
{
if(gao)
visz[6][num] = 1;
else
visz[6][num] = 0;
}
else if(x > 3 && x<= 6 && y > 6 && y<=9)
{
if(gao)
visz[8][num] = 1;
else
visz[8][num] = 0;
}
else
{
if(gao)
visz[9][num] = 1;
else
visz[9][num] = 0;
}
}
int checkz(int x,int y,int num)///检查z轴状态,进行改变
{
if(x <= 3 && y <= 3)
{
return visz[1][num] ;
}
else if(x > 3 && x <= 6 && y <= 3)
{
return visz[2][num] ;
}
else if(x > 6 && x <= 9 && y<= 3)
{
return visz[3][num];
}
else if(x <= 3 && y> 3 && y<= 6)
{
return visz[4][num] ;
}
else if( x <= 3 && y > 6 && y<=9)
{
return visz[7][num];
}
else if(x > 3 && x <= 6 && y > 3 && y<=6)
{
return visz[5][num] ;
}
else if(x > 6 && x <= 9 && y> 3 && y <= 6)
{
return visz[6][num] ;
}
else if(x > 3 && x<= 6 && y > 6)
{
return visz[8][num] ;
}
else
return visz[9][num] ;
}
void dfs(int x,int y)
{
if(flag)
return ;
if(x==9 && y==9 && !flag)
{
flag = 1;
for(int i = 1; i<= 9 ; i++)
{
for(int j = 1; j <= 9 ; j++)
{
printf("%d",Map[i][j]);
}
puts("");
}
return ;
}
if(x > 9 && flag )
return ;
if(y+1 > 9)
{
if(Mapold[x+1][1]!='0')
{
dfs(x+1,1);
}
else
{
for(int i = 1; i<= 9 ; i++)
{
if(!visx[x+1][i] && !visy[1][i] && checkz(x+1,1,i)==0)
{
visx[x+1][i] = 1;
visy[y+1][i] = 1;
z(x+1,1,i,1);
Map[x+1][1] = i;
dfs(x+1,1);
Map[x+1][1] = 0;
z(x+1,1,i,0);
visx[x+1][i] = 0;
visy[1][i] = 0;
}
}
}
}
else
{
if(Mapold[x][y+1]!='0')
{
dfs(x,y+1);
}
else
{
for(int i = 1; i<=9; i++)
{
if(!visx[x][i] && !visy[y+1][i] && checkz(x,y+1,i)==0)
{
visx[x][i] = 1;
visy[y+1][i] = 1;
z(x,y+1,i,1);
Map[x][y+1] = i;
dfs(x,y+1);
Map[x][y+1] = 0;
z(x,y+1,i,0);
visx[x][i] = 0;
visy[y+1][i] = 0;
}
}
}
}
}
int main()
{
int n;
scanf("%d",&n);
while(n--)
{flag = 0;
memset(visx,0,sizeof(visx));
memset(visy,0,sizeof(visy));
memset(visz,0,sizeof(visz));
memset(Mapold,0,sizeof(Mapold));
memset(Map,0,sizeof(Map));
for(int i = 1; i<= 9; i++)
{
scanf("%s",Mapold[i]+1);
}
for(int i =1; i<=9; i++)
{
for(int j = 1; j<=9; j++)
{
Map[i][j] = Mapold[i][j]-'0';
if(Map[i][j])
{
visx[i][Map[i][j]] = 1;
visy[j][Map[i][j]] = 1;
z(i,j,Map[i][j],1);
}
}
}
dfs(1,0);
if(flag == 0)
for(int i = 1; i<= 9 ; i++)
{
for(int j = 1; j<= 9 ; j++)
{
printf("%c",Mapold[i][j]);
}
puts("");
}
}
}
生成数独的方法如下:
你得到一个数独的解后,进行n次行或者列的变换,变化规则如下:设需要变化的两个数为x,y。那么第一次行列变换,则将所有行列的x,y互换位置。这就完成了第一次行列变换,进行n次后,再挖空数独,就能造出来一个数独了。但是这个方法我也不知道能不能制造出所有数独。