回溯法的应用之 数独游戏

 

数独我就不多说话了

没玩过的可以自己玩玩, 或者百科下:

http://zh.wikipedia.org/wiki/%E6%95%B0%E7%8B%AC

 

关键是回溯法。。

这次是巧妙的利用八皇后的基础搞出来的.

下面我就来好好讲将回溯法。

回溯法也称试探法,它的基本思想是:从问题的某一种状态(初始状态)出发,搜索从这种状态出发所能达到的所有“状态”,当一条路走到“尽头”的时候(不能再前进),再后退一步或若干步,从另一种可能“状态”出发,继续搜索,直到所有的“路径”(状态)都试探过。这种不断“前进”、不断“回溯”寻找解的方法,就称作“回溯法”。

上面的话一大推,你会发现很多废话,其实回溯就是倒着来,返回。



我们来回顾下本算法的回溯算法

代码:


  1 #include <iostream>
  2 
  3 using namespace std;
  4 
  5 #define   LEN  9
  6 
  7 int a[LEN][LEN] = {0};
  8 /*
  9  0 0 0 0 0 0 0 0 0
 10  0 0 3 0 0 0 0 0 0
 11  0 0 0 0 0 0 0 0 0
 12  0 0 0 0 0 0 0 0 0
 13  0 0 0 0 4 0 0 0 0
 14  0 0 0 9 0 0 0 0 0
 15  0 0 0 0 0 0 0 0 0
 16  0 0 0 0 0 0 0 0 0
 17  0 0 0 0 0 0 0 0 1
 18  */
 19 
 20 //查询该行里是否有这个值
 21 
 22 
 23 bool  Isvaild(int  count)
 24 {
 25 
 26    int i = count/9;
 27    int j = count%9; 
 28    
 29    //检测行
 30    for(int iter = 0;iter!=j;iter++)
 31    {
 32       
 33        if(a[i][iter]==a[i][j])
 34        {
 35           return 1;
 36        }
 37    }
 38    
 39    //检测列
 40    for(int iter=0;iter!=i;iter++)
 41    {
 42         if(a[iter][j]==a[i][j])
 43         {
 44           return 1;
 45         }
 46    }
 47    
 48    //检测九宫
 49    
 50    for(int p =i/3*3;p<(i/3+1)*3;p++)
 51    {
 52     for(int q=j/3*3;q<(j/3+1)*3;q++)
 53     { 
 54      
 55          if(p==i&&j==q)
 56          {
 57          
 58            continue;
 59          }
 60      
 61 
 62          if(a[p][q]==a[i][j])
 63             {
 64                 return 1;
 65             }
 66    }
 67 
 68    }
 69    return 0;
 70 }
 71 
 72 
 73 void print()
 74 {
 75 
 76     cout<<"数度的解集为"<<":"<<endl;
 77     for(int i=0;i<9;i++)
 78     {
 79         for(int j=0;j<9;j++)
 80         {
 81 
 82             cout<<a[i][j]<<" ";
 83         }
 84 
 85         cout<<endl;
 86     }
 87 
 88   cout<<endl;
 89 }
 90 
 91 void  first_chek(int count)
 92 {
 93     if(81 ==count)
 94     {
 95         print();
 96         return;
 97     }
 98 
 99     int  i = count/9;   //
100     int  j  = count%9;   //
101   
102     if(a[i][j]==0)
103      {
104         for(int n=1;n<=9;n++)
105         {
106             a[i][j] =  n;
107 
108             if(!Isvaild(count))  //这个值不冲突
109             {
110                 first_chek(count+1)           }
111 
112         }
113       
114          a[i][j] = 0;
115     }
116     
117 
118     else
119     {
120        
121         first_chek(count+1);
122     }
123 }
124 
125 
126 int main()
127 {
128 
129     a[1][2] = 3;
130     a[5][3] = 9;
131     a[8][8] = 1;
132     a[4][4] = 4;
133 
134 
135     first_chek(0);
136 
137 
138     return 0;
139 }

 

 



我们再来看下八皇后问题的回溯算法代码:

 

http://6520874.blog.163.com/blog/static/72582719201112032532836/ 

 

好的,回溯算法的关键模板是什么呢?


1。你要走的一共的布数,这个作为 最后的return

2.回溯的条件是判断是否存在。不存在再走一个步长




void fun(int n)

{

for()

if(总数==n

fun(n+1);

}



ok

模板已经给出了,我们按照这个模板能写出一些东西,

但是递归的关键还是递归表达式,递归的复杂度



好的,这些我们下次讲。





 

posted @ 2012-09-22 23:53  pipicfan  阅读(3037)  评论(1编辑  收藏  举报