【八皇后问题:白249页5.4】多重循环-递归-回溯-深搜(八皇后例题)

(1)什么时候用 多重循环,什么时候用递归

比如:
当N=3时候,我们可以这样写

但是实际情况

 

递归
search(k)表示当前是第k重循环,也就是枚举第k个位置的选择
void search(int k)
{ 
 for (int i=1; i<=N; i++) 
 {    
    a[k]=i;   
     search(k+1); 
 }
}
递归
添加边界条件
 if (k>N) {
	bool flag=true;
	for (int i=1; i<=N; i++)
		for (int j=i+1; j++; j<=N; j++)
			if (a[i]==a[j]) { //判断是否存在了相同的选择
				flag=false;
				break;
			}
	return;
} 

 

回溯
不想在最后才判断是否重复选择
开一个bool数组chosen[],初始化全为false
 for (int i=1; i<=N; i++) 
	if (!chosen[i]) {    
		a[k]=i;   
		chosen[i]=true;
 		search(k+1); 
		chosen[i]=false;
 }

  (2)综合应用八皇后问题

#include<iostream>
#include<iomanip>
#include<cstdio>
#include<cstdlib>
using namespace std;
bool b[100];        //b[j]=1 标记占领第j列的 
bool d[100],c[100]; //c[i..j]  d[i..j] 标记占领对角线 
int sum,a[100];    //a[i]=j 表示第i行列摆放皇后。 

int print()
{
	int i;
	sum++;
	cout<<"sum="<<sum<<endl;
	for(int i=1;i<=8;i++)
	  cout<<setw(4)<<a[i];
	  cout<<endl;
} 

int search(int i) //标记行
 {
 	int j; //标记列
	 for(j=1;j<=8;j++)
	   if((!b[j])&&(!c[i+j])&&(!d[i-j+7])) //结合行 两个对角线确定位置
	   {
	   	 a[i]=j;   //放置皇后位置 
		 b[j]=1;   //占领了第j列
		 c[i+j]=1; d[i-j+7]=1;   //标记此时对角线不能占用。
		 if(i==8) print(); //如果全占打印 
		  else search(i+1); 
		b[j]=0;
		c[i+j]=0;
		d[i-j+7]=0;
	   } 
 } 

int main()
{
  search(1);
  return 0;

}

  

posted on 2018-11-28 09:29  lcdxjsj  阅读(171)  评论(0编辑  收藏  举报

导航