题目出处:http://www.sqyoj.club/problem.php?id=1504
八皇后问题,经典的dfs。
通过本题讲解dfs的两种经典的算法框架:
框架一
int dfs(int k)
{
for (i=1;i<=算符种数;i++)
if (满足条件)
{
保存结果
if (到目的地) 输出解;
else Search(k+1);
回溯一步,恢复到保存结果之前的状态
}
}
框架二
int dfs(int k)
{
if (到目的地) 输出解;
else
for (i=1;i<=算符种数;i++)
if (满足条件)
{
保存结果;
Search(k+1);
回溯一步,恢复到保存结果之前的状态
}
}
画出4皇后的深搜树
演示两种不同框架的代码
回溯是指消除当前桢的记录,以进入当前桢循环的下一个算符
递,是指由当前桢递进到下一层的桢
归,是指由当前桢归去到上一层的桢
因为剪枝的存在,未必会发生递进
AC代码一
#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
int n=8,a[100],b[100],c[100],d[100],sum=0;
void print(){
sum++;
printf("%d",a[1]);
for(int i=2;i<=n;i++) printf(" %d",a[i]);
printf("\n");
}
void dfs(int i){
for(int j=1;j<=n;j++)
if(!b[j] && !c[i+j] && !d[i-j+n]){
b[j]=c[i+j]=d[i-j+n]=1;//染色
a[i]=j;//占领
if(i==n)print();
else dfs(i+1);
b[j]=c[i+j]=d[i-j+n]=0;//回溯
}
}
int main(){
//cin>>n;
dfs(1);
printf("sum=%d",sum);
return 0;
}
AC代码二
#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
int n=8,a[100],b[100],c[100],d[100],sum=0;
void print(){
sum++;
printf("%d",a[1]);
for(int i=2;i<=n;i++) printf(" %d",a[i]);
printf("\n");
}
void dfs(int i){
if(i==n+1)print();
else
for(int j=1;j<=n;j++)
if(!b[j] && !c[i+j] && !d[i-j+n]){
b[j]=c[i+j]=d[i-j+n]=1;//染色
a[i]=j;//占领
dfs(i+1);
b[j]=c[i+j]=d[i-j+n]=0;//回溯一步
}
}
int main(){
//cin>>n;
dfs(1);
printf("sum=%d",sum);
return 0;
}
int木匣框架Search(int k)
for (i=1;i<=算符种数;i++)
if (满足条件)
{
保存
结果
if (到目的地) 输出解;
else Search(k+1);
恢复:保存结果之前的状态{回溯一步}
}
}