前段时间出差在外闲得无事看到一个数独问题。有三题,脑子不好使,只做出前两题。想想不如用程序来实现。
我先把题放出来大家有兴趣研究一下。
8 | 5 | 7 | 1 | |||||
1 | 9 | 2 | ||||||
6 | 2 | |||||||
5 | 6 | 9 | ||||||
2 | 4 | 5 | 8 | |||||
8 | 1 | 2 | ||||||
4 | 9 | |||||||
4 | 6 | 5 | 7 | |||||
5 | 8 | 9 | 1 |
5 | 2 | |||||||
1 | 9 | 6 | 3 | |||||
3 | 5 | 7 | 6 | |||||
6 | 1 | 4 | 7 | |||||
7 | 2 | 6 | 4 | |||||
5 | 3 | 8 | 6 | |||||
9 | 7 | 8 | 3 | |||||
5 | 8 | 3 | 9 | |||||
8 | 7 |
6 | 1 | 7 | ||||||
1 | 9 | 3 | 6 | |||||
4 | ||||||||
5 | 2 | 8 | ||||||
8 | 1 | 7 | 2 | |||||
2 | 7 | 6 | ||||||
6 | ||||||||
7 | 6 | 5 | 3 | |||||
5 | 4 | 8 |
规则:
在9*9的格子中用1到9填满格子:
每一行都要用到1~9,位置不限;
每一列都要用到1~9,位置不限;
每3*3格子都要用到1~9,位置不限;
我的算法思想比较简单:穷举法,递归。
1、初始化:
新建两个数组A[9,9],B[9,9],他们的初始值都一样。
public static int[,,] A = new int[9,9,9];
public static int[,] B = new int[9,9];
for(int
for(int
A[i,j] = 0;
A[0,1]=6;
A[0,4]=1;
A[0,5]=7;
………………
A[8,3]=5;
A[8,4]=4;
A[8,7]=8;
A[8,8]=6;
for(int
for(int
B[m,n] = 0;
B[0,1]=6;
B[0,4]=1;
B[0,5]=7;
………………
B[8,3]=5;
B[8,4]=4;
B[8,7]=8;
B[8,8]=6;
递归过程:
public void JudgeNumber(int x,int
{
if(x<9&&y<9) //判断数组下标范围
{
if(A[x,y] == 0||A[x,y] != B[x,y]) //如果数组的值为零或者取得的值不等于B的值
{
for(int
{
A[x,y] = i; //循环付值
if(Pass(x,y)) //判断条件
{
if(Victory()) //成功
{
printShuzu();
return
}
if(y<8) //判断下一个数
JudgeNumber(x,y+1);
else
JudgeNumber(x+1,0);
}
}
A[x,y] = 0; //失败之后把值设为零,以便继续判断
}
else //判断下一个数
{
if(y<8)
JudgeNumber(x,y+1);
else
JudgeNumber(x+1,0);
}
}
}
public boolPass(int i,int
{
//判断横竖有无重复
for(int
{
if(b!=i)
if(A[i,j] == A[b,j])
return false;
if(b!=j)
if(A[i,j] == A[i,b])
return false;
}
//判断*3有无重复
int
int
int
int
for(int
for(int
if(q!=i&&k!=j)
if(A[i,j] == A[q,k])
return false;
return true;
}
/// <summary>
/// 在Pass情况下如果整个数组无0表示成功求解
/// </summary>
/// <returns></returns>
public bool
{
bool ax=false;
for(int
for(int
{
if( A[i,j] != 0)
ax =true;
else
return false;
}
return
}
本算法的问题:
1.穷举取值过多。不必从1~9全部取
2.成功后在递归里面不能跳出。
对问题1的改进:
1.新建3维数组A[9,9,9]
2初始判断,获取该位置可取值的范围
f
3.更改判断部分.
or(int
for(int
{
int[] B = new int[9];
for(int
B[d] = d+1;
if(A[i,j,0]==0)
{
for(int
{
A[i,j,0] = B[a];
for(int
{
if(b!=i)
if(A[i,j,0] == A[b,j,0])
B[a]=0;
if(b!=j)
if(A[i,j,0] == A[i,b,0])
B[a]=0;
}
int
int
int
int
for(int
for(int
if(q!=i&&k!=j)
if(A[i,j,0] == A[q,k,0])
B[a]=0;
A[i,j,0] = 0;
}
}
}
public void JudgeNumber(int x,int
{
if(x<9&&y<9)
{
if(A[x,y,0] == 0||A[x,y,0] != B[x,y])
{
for(int i=1;i<9;i++)//更改部分
{
if(A[x,y,i]!=0)//更改部分
{
A[x,y,0] = A[x,y,i];//更改部分
if(Pass(x,y))
{
if(Victory())
{
printShuzu();
//return ;
}
if(y<8)
JudgeNumber(x,y+1);
else
JudgeNumber(x+1,0);
}
}
}
A[x,y,0] = 0;
}
else
{
if(y<8)
JudgeNumber(x,y+1);
else
JudgeNumber(x+1,0);
}
}
}