深度优先搜索(DFS):
理解:一个沿树爬行的虫子,在一个交叉口他会首先随机选择一条分岔路口一直走下去直到死路为止,然后会返回到这个交叉口沿着另一条分支爬行下去,直到遍历所有可能的路径为止。
例题一:Lack Counting
#include<iostream>
using namespace std;
const int Max=101;
char a[Max][Max];
int n,m;
int cnt=0;
int nx,ny;
void input(int n,int m){
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
cin>>a[i][j];
}
}
}
void dfs(int x,int y){
a[x][y]='.';
for(int i=-1;i<=1;i++){
for(int j=-1;j<=1;j++){
nx=x+i;
ny=y+j;
if(nx<n&&nx>=0&&ny<m&&ny>=0&&a[nx][ny]=='W'){
dfs(nx,ny);
}
}
}
}
void solve(){
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
if(a[i][j]=='W'){
dfs(i,j);
cnt++;
//cout<<cnt<<endl;
}
}
}
cout<<cnt;
}
int main()
{
cin>>n>>m;
input(n,m);
solve();
return 0;
}
例题二:
Dungeon Master
代码:
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#include<math.h>
#include<queue>
using namespace std;
char map[50][50][50];//坐标
int L,R,C,sz,sx,sy;
int vis[50][50][50];//标记该点是否访问
int dir[6][3]= {{1,0,0},{-1,0,0},{0,1,0},{0,-1,0},{0,0,1},{0,0,-1}};//前后左右上下六个方向坐标
struct node
{
int x,y,z,t;
};
int check(int z,int x,int y)//如果可以通过返回1,不可以通过返回0
{
if(z>=0&&z<L&&x>=0&&x<R&&y>=0&&y<C&&map[z][x][y]!='#')//保证坐标在取值范围之内,然后就是
{ //'.'作为路向后移动
return 1;
}
else
{
return 0;
}
}
void bfs()//深搜寻找可以通过的路径
{
memset(vis,0,sizeof(vis));//将VIS初始化
queue<node>q;//定义一个队列q存储符合条件的坐标
node st,ed;
st.z=sz;
st.x=sx;
st.y=sy;
st.t=0;
vis[st.z][st.x][st.y]=1;
q.push(st);//将出发点入队
while(!q.empty())//如果队列q为空就证明没找到可以通过的路径
{
st=q.front();//首先对队首元素进行深搜看六个方向有没有可以通路的
q.pop();
if(map[st.z][st.x][st.y]=='E')//如果队首元素为E证明逃出地牢
{
printf("Escaped in %d minute(s).\n",st.t);
return;
}
for(int i=0; i<6; i++)//对六个方向进行遍历
{
ed=st;
ed.z+=dir[i][0];
ed.x+=dir[i][1];
ed.y+=dir[i][2];
if(check(ed.z,ed.x,ed.y)==0)//如果此方向不能通过就继续对其他方向进行搜索
{
continue;
}
ed.t++;//可以通过时间加一
if(vis[ed.z][ed.x][ed.y]==0)
{
vis[ed.z][ed.x][ed.y]=1;
q.push(ed);//(!注意!注意)找到了下一条要走的路口,入栈,这里是移动的关键
} //从进入入口之后不断地往后移动的关键语句
}
}
printf("Trapped!\n");
}
int main()
{
while(~scanf("%d%d%d",&L,&R,&C)&&L&&R&&C)//这里输入就保证了当L、R、C为0的时候就不处理
{
for(int i=0; i<L; i++)//输入各个点的坐标
{
for(int j=0; j<R; j++)
{
scanf("%s",map[i][j]); //用字符串的方式先输入第几层
for(int k=0; k<C; k++)
{
if(map[i][j][k]=='S') //然后判断这一层的第几个是S作为入口
{
sz=i; //对全局变量赋值
sx=j;
sy=k;
}
}
}
}
bfs();
}
}