數獨我就不多說話了
沒玩過的可以自己玩玩, 或者百科下:
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
模板已經給出了,我們按照這個模板能寫出一些東西,
但是遞歸的關鍵還是遞歸表達式,遞歸的復雜度
好的,這些我們下次講。