遠端執行緒注入
阿新 • • 發佈:2020-12-13
回溯演算法——八皇后
什麼是八皇后??
在8×8格的國際象棋上擺放8個皇后,使其不能互相攻擊,即任意兩個皇后都不能處於同一行、同一列或同一斜線上,問有多少種擺法。
什麼是回溯??
回溯搜尋是深度優先搜尋(DFS)的一種,回溯法通俗的將其採用的思想是“一直向下走,走不通就掉頭”。
我們一般在求解八皇后問題的時候說使用的是回溯法,本質也是深搜。
思路
將第一行的皇后放在第一列以後,第二行的皇后放在第一列已經會產生攻擊。這時候不必繼續放第三行的皇后,而將第二行的皇后到第二列,繼續攻擊,放入第三列,不攻擊了才開始進入第三行。如此可依次放下1-5行的皇后。將每個皇后能攻擊到的位置檢查之後,發現第六行的皇后無處安身。這時回溯到第五行的皇后,將其位置由第4列調整為第8列,進入第六行,發現皇后依然無處安身,再次回溯。此第五行已經列舉完所有情況,回溯至第四行,將其由第2列移至第7列,再進入下一行繼續。按此演算法流程最終找到下圖的解,成功在棋盤裡放下了8個“和平共處”的皇后。
#include<stdio.h>
#include<math.h>
int a[9],book[9],sum=0;
//a陣列的下標表示行,裡面存放的數字表示列
//book陣列用來標記這一列是否放下了皇后
//sum用來對可行的放置方法基計數
void dfs(int step);//step表示第幾行
int main() {
dfs(1);//從第一行開始;
printf("%d", sum);
}
void dfs(int step) {
if (step == 9) {//來到第九行說明八行已經放完
sum++;//計數
return;//回溯
}
for (int i = 1; i <= 8; i++) {//i表示列
if (book[i] == 0) {//book[i]為零表示這一列沒有放下皇后
a[step] = i;//在(step,i)處放下皇后
/*檢測剛剛放下的皇后是否會與之前的皇后衝突,即檢測對角線*/
int flag = 1;
for (int j = 1; j <step; j++)
if (abs(a[step] - a[j]) == abs(step - j))//當位於對角線上的皇后的橫縱之差的絕對值相等(y=x或y=-x,懂吧)
flag = 0;
/*flag為1時表示不會衝突*/
if (flag) {
book[i] = 1;
dfs(step + 1);//進入下行
book[i] = 0;
}
else continue;
}
}
return;//回溯
}