或許很多讀者尚未發現,八皇后問題存在乙個重要數學規律。如何運用這個規律對演算法進行效能優化,使得約束函式的時間複雜度從o(n)降至o(1),相信是每乙個演算法愛好者所關心的。今天寫這篇文章的目的便是帶大家一起**一下,八皇后問題之中到底存在什麼樣的數學規律,能夠擺脫傳統的遞迴解法,使得效能提公升乙個量級。
先放出基本遞迴解法的**吧!
public int caculate(int locationrecord, int n, int curhang, int totalcount)
}if (hasconflict == false) else }}
return totalcount;
}
想必大部分讀者都掌握了基本的遞迴解法,這裡大致介紹一下吧。首先強調一下規則:棋盤中,同一行,同一列,同一條對角線上不能同時存在兩個皇后。按照規則,我們可以選擇按行來遍歷,每一行放置乙個,也可以選擇按列來遍歷,每一列放置乙個。上面解法使用按行遍歷,從第一行遍歷至第八行,每一行找乙個合法位置放置皇后。當第八行(最後一行)成功放置皇后之後,便找到乙個解,然後return回溯,繼續找下乙個解。
上述**中,在每一行元素遍歷中,都會檢查是否存在衝突,這個檢查也成為約束函式。檢查的方式很簡單,就是開乙個for迴圈,判斷當前行的當前元素是否和當前行之上的任一一行中皇后存在衝突,如果衝突就繼續遍歷下乙個元素,如果不衝突就在當前元素位置放置皇后,並繼續遍歷下一行。這個約束函式的實現很簡單,也很直觀易懂。但是卻造成了o(n)的複雜度,未免有點讓人難以接受。
怎麼去優化約束函式呢?我們首先來看一下存在衝突時的情況。01
2345
670x1
1x22x7
x33x8x44x9
x5x105x6
x116
x127
現在我們來做出一波分析。x1,x2,x3之間互相衝突,x1座標為(0,1),x2座標為(1,2),x3座標為(2,3),觀察可發現乙個規律,它們在同一條主對角線上,並且縱座標減去橫座標值恒為1。同樣的,在同一條主對角線上的x7,x8,x9也存在相互衝突,x7座標(2,1),x8座標(3,2),x9座標(4,3),它們的縱座標減去橫座標值恒為-1。到這裡,我們已經發現並確定這個規律了,同一對角線上的元素,它們的橫縱座標差值是相等的。
不不,這話說的太早,哈哈!是不是忽略副對角線的情況了,好的,我們再分析下副對角線的情況。x4,x5,x6在同一副對角線並且相互衝突,x4座標(3,7,),x5座標(4,6),x6座標(5,5),仔細觀察可得知,它們的橫座標值加縱座標值之和恒為10,x10,x11,x12亦是這個規律。
好的,現在規律已經找出來了,後面就是怎麼去程式設計實現啦。
同一對角線的元素既然橫縱座標差值相等,那麼我們就可以通過乙個布林陣列來標標識某條對角線是否存在皇后,設這個陣列為v[16],比如某個元素位置放置了皇后,則在陣列v中以這個元素橫縱座標差值為下標的地方,設定值為true,之後遍歷到該對角線上其他元素時,只需檢查一下陣列中以橫縱座標差值為下標處的值為不為true就行,為true則視為存在衝突,當前元素位置不可取。這個檢查只需一步操作就行,也就是o(1)的複雜度。
是不是很激動,運用乙個數學小規律,就把o(n)的複雜段降為了o(1)。
好了,八皇后問題規律總結到這裡就結束啦,大夥兒可以操刀寫一波**了!順便看下耗時是不是縮短了,嘿嘿!
演算法 八皇后問題
問題簡述 八皇后問題是乙個以西洋棋為背景的問題 如何能夠在8 8的西洋棋棋盤上放置八個皇后,使得任何乙個皇后都無法直接吃掉其他的皇后?為了達到此目的,任兩個皇后都不能處於同一條橫行 縱行或斜線上。八皇后問題可以推廣為更一般的n皇后擺放問題 這時棋盤的大小變為n1 n1,而皇后個數也變成n2。而且僅當...
演算法 八皇后問題
問題描述 八皇后問題是乙個以西洋棋為背景的問題 如何能夠在8 8的西洋棋棋盤上放置八個皇后,使得任何乙個皇后都無法直接吃掉其他的皇后?為了達到此目的,任兩個皇后都不能處於同一條橫行 縱行或斜線上。八皇后問題可以推廣為更一般的n皇后擺放問題 這時棋盤的大小變為n n,而皇后個數也變成n。當且僅當n 1...
演算法 八皇后問題
created by xiaoyu on 2019 10 6.include include using namespace std const int n 8 int board n n int tot 0 int valid int x,int y for int i 0 i x i retur...