前段时间出差在外闲得无事看到一个数独问题。有三题,脑子不好使,只做出前两题。想想不如用程序来实现。

我先把题放出来大家有兴趣研究一下。



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);
                   }
              }
         }