sqyoj:1504八皇后问题,及对回溯、递归的理解

题目出处: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
#include
#include
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
#include
#include
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);

    恢复:保存结果之前的状态{回溯一步}

     }

 }

 

你可能感兴趣的:(sqyoj:1504八皇后问题,及对回溯、递归的理解)