搜尋&回溯——N皇后(hdu2553)
阿新 • • 發佈:2019-01-22
題目連結:
題目描述:
在N*N的方格棋盤放置了N個皇后,使得它們不相互攻擊(即任意2個皇后不允許處在同一排,同一列,也不允許處在與棋盤邊框成45角的斜線上。
你的任務是,對於給定的N,求出有多少種合法的放置方法。
解決思路:
回溯官方課題~用這道題理解回溯再合適不過了,下面的程式碼也是初學回溯時所寫的,感覺自己萌萌噠~
百科一下回溯法:
回溯演算法也叫試探法,它是一種系統地搜尋問題的解的方法。回溯演算法的基本思想是:從一條路往前走,能進則進,不能進則退回來,換一條路再試。用回溯演算法解決問題的一般步驟為:
1、定義一個解空間,它包含問題的解。
2、利用適於搜尋的方法組織解空間。
3、利用深度優先法搜尋解空間。
4、利用限界函式避免移動到不可能產生解的子空間。
問題的解空間通常是在搜尋問題的解的過程中動態產生的,這是回溯演算法的一個重要特性。
其實說白了 就是 遞迴前改變一個狀態,遞迴後再改回來~2333333 比如說
n++;
f(n) //試探下一步
n--;
N皇后即,當前點可以放置皇后就試探性的放,當其所有子節點遍歷完之後再接著考慮後面的選擇
shu[i]=you[m+i]=zuo[m-i+n]=1; //假設採取當前方案。
hs(m+1); //走到下一行。
shu[i]=you[m+i]=zuo[m-i+n]=0; //執行完回溯還原。
完整程式碼:
#include<stdio.h> #include<string.h> int shu[110],zuo[110],you[110]; //記錄"上""左""右"狀態。 int n,sum; int x[11]={0,1,0,0,2,10,4,40,92,352,724};//N=1~10答案,測試資料。 void hs(int m)//無剪枝完全回溯,對於每個可選擇路線都會走一遍,然後還原。 { int i; if(n<m) //如果n<m了,即最後一行也走完了,sum++並返回。 { sum++; return; } for(i=1;i<=n;i++) //回溯開始 { if(!shu[i]&&!you[m+i]&&!zuo[m-i+n]) //如果滿足三個條件為0(可選) //注意zuo,you陣列要是測試資料的2倍,左邊減到負值時要加個n即從最右開始。 { shu[i]=you[m+i]=zuo[m-i+n]=1; //假設採取當前方案。 hs(m+1); //走到下一行。 shu[i]=you[m+i]=zuo[m-i+n]=0; //執行完回溯還原。 } } } int a[11]; int main() { int nn; for(n=1;n<=10;n++) //打表 { memset(shu,0,sizeof(n)); //三個記錄狀態的陣列清零 memset(zuo,0,sizeof(n)); memset(you,0,sizeof(n)); sum=0; hs(1); //從第一行開始 a[n]=sum; //結果存在a數組裡 } while(~scanf("%d",&nn)&&nn) { printf("%d\n",a[nn]); } }