版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
在介绍八皇后问题之前我们先说说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能太高不少的效率。其实这个方法也可以叫剪枝,但不是我们今天讨论的重点。
我们模拟决策之后,就可以写代码了,别忘了工具人数组一定要放在函数里面,还有就是对角线一定要注意,注意好这几点,想必大家很容易就能把此题解出来了。=。=