数独游戏非常好玩,可以训练玩家的逻辑推理能力。数独游戏的规则是:
1.在9×9的大九宫格内,已给定若干数字,其他宫位留白,玩家需要自己按照逻辑推敲出剩下的空格里是什么数字。
2.必须满足的条件:每一行与每一列都有1到9的数字,每个小九宫格里也有1到9的数字,并且一个数字在每行、每列及每个小九宫格里只能出现一次,既不能重复也不能少。
3.每个数独游戏都可根据给定的数字为线索,推算解答出来,而且每个数独游戏的解答方案都是独一无二的。如下例:
3
6
5
2
9
4
8
2
9
3
7
1
8
5
6
1
7
4
3
3
5
7
2
3
4
7
8
1
4
4
9
8
6
5
3
做数独游戏的思路是,比如第一行,缺1,7,8三个数字。先把1拿出来,看第一行的三个空格中的一个空格所在的列及这个空格所在的小九宫,若没有1,则这个空格有可能填1。若这一行还有其他的空格也有可能填1,则不能填1,只有这一行其他的空格不能填1时,才能确定这个空格填1。如此进行下去,直到填完所有的空格。
当然也可以先查某一列缺哪些数字,判断这一列上的某个空格所在的行及小九宫里有没有要填的数字,来确定填哪个数字;也可以先查某个小九宫里缺哪些数字,判断这个小九宫里的某个空格所在的行、列有没有要填的数字,来确定填哪个数字。这三个方法可以灵活选用,很快就能得到答案
根据上面的分析,我们可以编程让计算机来做数独游戏,如下面的c语言程序
main()
{
static int a[9][9]={
{0,3,6,5,2,0,0,9,4},{0,0,8,0,0,0,0,2},{0,0,9,0,3,7,1,8},
{0,5,0,0,6,1},{7,0,0,0,4,0,0,0,3},{0,0,0,3,5,0,0,7},
{0,2,3,4,7,0,8},{0,1,0,0,0,0,4},{4,9,0,0,8,6,5,3}};
int b[9],i,j,k,l,m,n,jx,jgrow,jgcol,kt,ktw,leap;
printf("\n");
for (i=0;i<9;i++) /*输出原题*/
{
for (j=0;j<9;j++)
printf(" %d ",a[i][j]);
printf("\n");
}
jx=1;
while (jx) /*做游戏*/
{
for(i=0;i<9;i++)
{
for(k=0;k<9;k++) b[k]=k+1;
for(j=0;j<9;j++)
if(a[i][j]!=0)
for (k=0;k<9;k++)
if(b[k]==a[i][j]) b[k]=0;/*查这一行缺哪些数字,b[0]到b[8]中不为0的数即为这一行中缺少的数*/
for (k=0;k<9;k++)
if (b[k]!=0)
{kt=0;/*可填标志量*/
for (j=0;j<9;j++)
if (a[i][j]==0)
{ leap=1;/*a[i][j]这个空格所在的列及小九宫有无要填的数字*/
for (l=0;l<9;l++)
if (a[l][j]==b[k]) leap=0;/*这一列有这个数,不可填*/
jgrow=(i/3)*3;jgcol=(j/3)*3;
for (l=0;l<3;l++)
for (m=0;m<3;m++)
if(a[jgrow+l][jgcol+m]==b[k]) leap=0;/*小九宫内有这个数,不可填*/
if (leap) {kt++;if (kt==1) ktw=j;} /*第一次可以填时,记下坐标。*/
}
if (kt==1) {a[i][ktw]=b[k];kt=0;} /*填一个数字*/
}
}
jx=0;
for(i=0;i<9;i++)
for(j=0;j<9;j++)
if (a[i][j]==0) jx=1;
}
printf("\n");
for (i=0;i<9;i++)
{ for (j=0;j<9;j++)
printf(" %d ",a[i][j]);
printf("\n");
}
}
上面的程序的算法,是先查找每一行上缺哪一个数字,然后判断每一个所缺的数字能否填在这一行的空格上,能填的立即填上,不能填的等下一轮查找时继续判断,直到填完所有的空格。
我们若要先查找每一列上缺哪一个数字,与上面的程序类似,可写出下面的程序,只是要特别注意数组的下标。
main()
{
static int a[9][9]={
{0,3,6,5,2,0,0,9,4},{0,0,8,0,0,0,0,2},{0,0,9,0,3,7,1,8},
{0,5,0,0,6,1},{7,0,0,0,4,0,0,0,3},{0,0,0,3,5,0,0,7},
{0,2,3,4,7,0,8},{0,1,0,0,0,0,4},{4,9,0,0,8,6,5,3}};
int b[9],i,j,k,l,m,jx,jgrow,jgcol,kt,ktw,leap;
printf("\n");
for (i=0;i<9;i++)
{ for (j=0;j<9;j++)
printf(" %d ",a[i][j]);
printf("\n");
}
jx=1;
while (jx)
{
for(i=0;i<9;i++)
{
for(k=0;k<9;k++) b[k]=k+1;
for(j=0;j<9;j++)
if(a[j][i]!=0)
for (k=0;k<9;k++)
if(b[k]==a[j][i]) b[k]=0;
for (k=0;k<9;k++)
if (b[k]!=0)
{
kt=0;
for (j=0;j<9;j++)
if (a[j][i]==0)
{
leap=1;
for (l=0;l<9;l++)
if (a[j][l]==b[k]) leap=0;
jgrow=(j/3)*3;jgcol=(i/3)*3;
for (l=0;l<3;l++)
for (m=0;m<3;m++)
if (a[jgrow+l][jgcol+m]==b[k]) leap=0;
if (leap) {kt++;if (kt==1) ktw=j;}
}
if (kt==1) {a[ktw][i]=b[k];kt=0;}
}
}
jx=0;
for(i=0;i<9;i++)
for(j=0;j<9;j++)
if(a[i][j]==0) jx=1;
}
printf("\n");
for (i=0;i<9;i++)
{ for (j=0;j<9;j++)
printf(" %d ",a[i][j]);
printf("\n");
}
}
我们若要先查找每一个小九宫里缺哪几个数字,与上面的程序类似,可写出下面的程序:
main()
{
static int a[9][9]={ {0,3,6,5,2,0,0,9,4},{0,0,8,0,0,0,0,2,6},{0,0,9,0,3,7,1,8},{0,5,0,0,6,1},{7,0,0,0,4,0,0,0,3},{0,0,0,3,5,0,0,7},{0,2,3,4,7,0,8},{0,1,0,0,0,0,4},{4,9,0,0,8,6,5,3}};
int b[9],i,j,k,l,m,p,q,jx,kt,ktrow,ktcol,leap;
printf("\n");
for (i=0;i<9;i++)
{ for (j=0;j<9;j++)
printf(" %d ",a[i][j]);
printf("\n");
}
jx=1;
while (jx)
{
for (i=0;i<9;i+=3)
{
for (j=0;j<9;j+=3)
{
for(k=0;k<9;k++) b[k]=k+1;
for (l=i;l
for (m=j;m
for (k=0;k<9;k++)
if (b[k]==a[l][m]) b[k]=0;
for (k=0;k<9;k++)
if (b[k]!=0)
{
kt=0;
for (l=i;l
for (m=j;m
if (a[l][m]==0)
{
leap=1;
for (p=0;p<9;p++)
if (a[l][p]==b[k]) leap=0;
for (p=0;p<9;p++)
if (a[p][m]==b[k]) leap=0;
if (leap) {kt++;if (kt==1) ktrow=l,ktcol=m;}
}
if (kt==1) {a[ktrow][ktcol]=b[k];kt=0;}
}
}
}
jx=0;
for (i=0;i<9;i++)
for (j=0;j<9;j++)
if (a[i][j]==0) jx=1;
}
printf("\n");
for (i=0;i<9;i++)
{ for (j=0;j<9;j++)
printf(" %d ",a[i][j]);
printf("\n");
}
}
上面的三个程序(已通过验证)可单独运行,也可以组合在一块,提高效率。上题的答案如下:
1
3
6
5
2
8
7
9
4
5
7
8
9
1
4
3
2
6
2
4
9
6
3
7
1
8
5
3
5
2
7
6
1
9
4
8
7
6
1
8
4
9
2
5
3
9
8
4
3
5
2
6
7
1
6
2
3
4
7
5
8
1
9
8
1
5
2
9
3
4
6
7
4
9
7
1
8
6
5
3
2
下面的数独游戏,你会做吗?
1
9
2
2
5
3
6
1
8
9
3
2
3
5
7
1
4
9
7
9
5
1
7
9
2
5
4
9
3
8
(答案)
1
7
9
8
6
4
5
2
3
2
4
8
5
3
9
7
6
1
3
5
6
1
7
2
8
4
9
9
1
4
6
5
3
2
8
7
8
3
5
7
2
1
4
9
6
6
2
7
9
4
8
1
3
5
4
6
1
3
8
7
9
5
2
7
8
3
2
9
5
6
1
4
5
9
2
4
1
6
2
7
8