深搜这个算法相信大家肯定都不陌生吧,它是算法中基础中的基础,它运用到的就是递归了,它还隐式的包含了一种数据结构——栈,我在理解这个算法的时候可吃了不少苦头,花了不少时间,但是一旦掌握,你的思维可以说会提升一个档次,下面让我们一起来看看什么是深搜算法。
算法例题:要说涉及到深搜的问题,不得不说一个名字——n皇后问题,其中n皇后问题中最出名的就是把皇后了,下面我们看看这题目是怎么样的。
首 先来看这张图片:这是n==8时候的一种情况,但是这只是其中的一种情况,我们要怎么输出所有的情况呢,如果用一般的数组来写的话显然不可能,顶多只能找 到所有解中的某几组,我们试试深搜,当找到其中的一组解之后,使程序在尝试搜索下一组解,直至所有的解都搜索完毕,咦?好像可以做到的样子,行,那我们来 试试吧。
#include<iostream> #include<math.h> using namespace std; int a[8][8],b[8];//a数组表示棋盘最大为8*8,b数组用来表示列,如要表示第i行的列就表示为b[i] int n,sum; bool check(int n) { for(int i=0;i<n;i++) { //b[i]==b[n]来判断是否同一列,abs(i-n)==abs(b[i]-b[n])来判断是否同一对角线 //这个判断对角线的方法读者稍微想一下就能明白 if(b[i]==b[n]||abs(i-n)==abs(b[i]-b[n])) return 0; } return 1; } void dfs(int x) { for(int i=0;i<n;i++) { b[x]=i;//(x,b[x]) if(check(x))//来判断是否跟已经放好在同一列,或是同一个对角线上 { if(x==n-1)//若棋子已经放到第n行了,则说明已经出现一种情况了,则sum+1 { sum++; //下面这段打注释的代码是输出每种情况时棋盘状态,读者可先删除 /*a[x][b[x]]=1; for(int p=0;p<n;p++) { for(int q=0;q<n;q++) { cout<<a[p][q]<<" "; } cout<<endl; } cout<<endl; a[x][b[x]]=0;*/ return;//返回寻找下一种情况 } else { a[x][b[x]]=1;//放上棋子 dfs(x+1);//x还没放到第n行则继续放 a[x][b[x]]=0;//将原来已放的棋子拿掉 } } } } int main() { while(scanf("%d",&n)!=EOF) { memset(a,0,sizeof(a)); memset(b,0,sizeof(b)); sum=0; dfs(0);//从第0行开始搜 cout<<sum<<endl; } return 0; }