標籤:style blog http color os io 資料 for
演算法就是明白了感覺很簡單,不理解就感覺那些代碼是天書。
第一次接觸N皇后問題是在我們的C++教材上,感覺挺困難的。我們教材上給了八皇后的代碼,尼瑪,就是一個八重迴圈。
好了,回到正題
vis數組就是儲存了三個方向是否會發生衝突,如果有衝突則不再搜尋。
因為我們是逐行搜尋,所以不會出現一行上有兩個皇后的問題。
主對角線上的規律就是,每條線上的行和列的差為定值;
副對角線是行和列的和為定值。
這樣就很容易理解代碼中 vis[1][col + row] 和 vis[2][n - col + row]的含義了,分別代表副對角線和主對角線
關於逾時,由於輸入資料比較多,所以打表是個不錯的選擇。
另外,這裡有一篇很詳細的文章講用位元運算來代替vis數組,馬克,以後再看!
http://www.cnblogs.com/gj-Acit/archive/2013/08/04/3236148.html
1 //#define LOCAL 2 #include <iostream> 3 #include <cstdio> 4 #include <cstring> 5 using namespace std; 6 7 int cnt, n, vis[3][25]; 8 int ans[12]; 9 10 void DFS(int row)11 {12 if(row == n)13 {14 ++cnt;15 return;16 }17 for(int col = 0; col < n; ++col)18 {19 if(!(vis[0][col] || vis[1][col + row] || vis[2][n - col + row]))20 {21 vis[0][col] = vis[1][col + row] = vis[2][n - col + row] = 1;22 DFS(row + 1);23 vis[0][col] = vis[1][col + row] = vis[2][n - col + row] = 0;24 }25 }26 }27 28 void Init()29 {30 for(n = 1; n <= 10; ++n)31 {32 cnt = 0;33 memset(vis, 0, sizeof(vis));34 DFS(0);35 ans[n] = cnt;36 }37 }38 39 int main(void)40 {41 #ifdef LOCAL42 freopen("2553in.txt", "r", stdin);43 #endif44 45 Init();46 int num;47 while(scanf("%d", &num) && num)48 printf("%d\n", ans[num]);49 return 0;50 }代碼君