題意:例如在八皇后問題中,8*8的方格中,要求放置八個皇后。要求兩兩皇后均不在同一行,不在同一列,而且不在同一個連線上。ios
思路:考慮到每一行每一列只能有一個皇后,這就能夠當作是n的全排列問題,只要稍加改進就能夠實現n皇后問題。樸素的作法是,每一次獲得一個排列數時,判斷兩兩皇后之間是否合法,但這種作法並非最優的。更好的作法是,每次要放置第index行皇后時,判斷該位置是否已經非法,若是非法則後續不少操做都不須要執行,相似於回溯,但這個又有點不同。若是合法,則添加,遞歸執行下一行的皇后擺法問題。spa
踩坑點:八皇后問題的遞歸回溯實現要對遞歸理解深刻一些,不然本身可能說服不了本身,思惟容易死循環。其次有一點,須要開闢一段空間,存放已經解決好的n個皇后的問題,如8皇后問題已然解決,就將其存入memory[n] 記憶單元去,下一次直接輸出便可。若是不這樣折騰,就會TLE了。code
#include <iostream> #include <cstdio> #include <math.h> using namespace std; const int MAXSIZE = 100; int n,P[MAXSIZE],cnt=0; int memory[MAXSIZE] = {0}; bool hashTable[MAXSIZE] = {false}; void Nqueue(int index){ if(index == n+1){ cnt++; memory[n]++; return; } for(int x=1;x<=n;x++){ //第x列 if(hashTable[x] == false){ //第x列尚未皇后 bool f = true; //f爲true表示當前皇后不會和以前的皇后衝突 for(int pre=1;pre<index;pre++){ if(abs(index-pre) == abs(x-P[pre])){ f = false; break; } } if(f){ P[index] = x; //將當前index行的皇后放在x列上 hashTable[x] = true; Nqueue(index + 1); //處理下一行 hashTable[x] = false; //處理一個擺法完畢,遞歸回掉 } } } } int main() { std::ios::sync_with_stdio(false); cin.tie(0); while(scanf("%d",&n)!=EOF && n!=0){ cnt = 0; if(memory[n]==0){ Nqueue(1); //從第一行開始 cout << cnt << endl; }else cout << memory[n] << endl; } return 0; }