在介紹八皇后問題之前我們先說說dfs吧
DFS–深度優先搜索
咱們先來看看我的dfs入坑題:指數型枚舉
#include<iostream>
using namespace std;
int n;
void dfs(int k,int choose)
{
if(k==n)
{
for(int i=0;i<n;i++)
{
if(choose>>i&1) cout<<i+1<<" ";
}
puts("");
return;
}
dfs(k+1,choose);//不選
dfs(k+1,choose|(1<<k));//選
}
int main(){
freopen("data.in","r",stdin);
freopen("data.out","w",stdout);
cin>>n;
dfs(0,0);
return 0;
}
//輸入:3
//輸出:
//3
//2
//2 3
//1
//1 3
//1 2
//1 2 3
這道題比較經典,可以看出dfs讓我們能暴力枚舉了所有的決策(選或者不選),如果你能理解這題那麼恭喜你,你dfs入門了。在數據量較小時暴力dfs無疑時非常優秀的選擇。好下面我們直接給出八皇后問題的代碼。
#include<iostream>
using namespace std;
int queen[8][8];//當然也可以用二進制表示但可能比較複雜,咱們就不自己難爲自己了
int res=0;
void copy(int a[8][8],int b[8][8])
{
for(int i=0;i<8;i++)
for(int j=0;j<8;j++)
a[i][j]=b[i][j];
}
void work(int a,int b)//選中a行b列
{
for(int i=0;i<8;i++)
queen[a][i]=1;
for(int i=0;i<8;i++)
queen[i][b]=1;
//對角線比較騷,咱們寫的細心一點就不會錯了
//先寫主對角線
int d=a-b;
int i=a-b,j=0;
while(i<8&&j<8)
{
if(i>=0&&j>=0)
queen[i][j]=1;
i++;
j++;
}
//最後
d=a+b;
i=a+b,j=0;
while(i>=0&&j<8)
{
if(i<8&&j>=0)
queen[i][j]=1;
i--;
j++;
}
}
void dfs(int k)
{
if(k==8)
{
res++;
return;
}
int i=k;
int g[8][8];//工具人放函數裏面不容易錯還舒服一點
copy(g,queen);
for(int j=0;j<8;j++)
{
if(!queen[i][j])
{
work(i,j);
dfs(i+1);
copy(queen,g);//還原現場
}
}
}
int main(){
freopen("data.in","r",stdin);
freopen("data.out","w",stdout);
dfs(0);
cout<<res<<endl;
return 0;
}
八皇后問題時道非常經典的dfs問題,與上題類似我們枚舉所有決策就可以了,與之不同的是我們很容易分析出每行(列)有且只有一個皇后,與之不符就一定不行,在此基礎上dfs能太高不少的效率。其實這個方法也可以叫剪枝,但不是我們今天討論的重點。
我們模擬決策之後,就可以寫代碼了,別忘了工具人數組一定要放在函數裏面,還有就是對角線一定要注意,注意好這幾點,想必大家很容易就能把此題解出來了。=。=