八皇后問題(回溯的演算法)
阿新 • • 發佈:2018-11-15
八皇后問題是經典的回溯演算法案例,但是對初學者有點難以理解...
基本思路是,從第一個皇后開始放置,同時設定列和左斜和右斜放置標誌(如果是從列開始的就設定行的標誌)
第i行遍歷,如果沒有能夠放的位置,直接退出函式(也就是不用管),如果沒有放到8個,就呼叫下一個函式,但是仍然在這一級函式之內,所以後續需要回溯以便進行下一個點的搜尋。
這樣是按照第一行從第一個字開始的輸出,如果按列的話,轉置矩陣2333333,程式碼如下:
/* 經典回溯 八皇后問題 按照每一行開始搜尋 by Dr.ls */ #include<iostream> using namespace std; const int size = 9; int num = 0; int q[9];//記錄每個行的皇后佔用的列號 bool line[9];//所在列 bool zuo[17];//所在左斜線i+j bool you[17];//右斜線 void set(int i) { int j, k, m; for (j = 1; j <= 8; j++) { if ((line[j] == true) && (you[i - j + 9] == true) && (zuo[i + j] == true)) { q[i] = j;//佔用ij位置 line[j] = false; you[i - j + 9] = false; zuo[i + j] = false;//所在列,斜線均被佔用 if (i < 8)//未到最後一行就呼叫下一行的函式放置 { set(i + 1); } else // 如果已經放完8個皇后 { num++; // 方案數加1 cout << num << endl; // 輸出方案號 char zz[17][17]; for (m = 1; m <= 8; m++) { for (k = 1; k <= 8; k++) { if (k == q[m]) { zz[m][k] = '*'; } else if (k != q[m]) { zz[m][k] = '.'; } } }//畫棋盤 for (k = 1; k <= 8; k++) { for (m = 1; m <= 8; m++) { cout << ' ' << zz[k][m]; } cout << endl;//輸出結果 } } line[j] = true; you[i - j + 9] = true; zuo[i + j] = true;//回溯演算法,裝作無事發生 } } } int main() { int i; num = 0; for (i = 1; i <= 8; i++) { line[i] = true; } for (i = 1; i <= 16; i++) { zuo[i] = true; you[i] = true; } set(1);//從第一行開始放 return 0; }