简单来说dfs适用于搜索所有情况的解,bfs适用求最小路径;
大家都知道,AiR_H和zbt是好朋友。AiR_H十分喜欢研究历史,这周末他想去山西一个神秘的地方来学习山西的历史,便想拉上zbt一起去。AiR_H对zbt说:山西,因居太行山之西而得名,简称“晋”,东依太行山,西、南依吕梁山、黄河,北依长城,与河北、河南、陕西、内蒙古等省区为界。介于北纬34°34′—40°44′,东经110°14′—114°33′之间,总面积15.67万平方千米…………zbt一脸懵逼,表示,我去,我去还不行吗。他们来到这个无人管理但是有一套自动开门锁门系统神秘的高楼。正在他们在最高楼观光的时候,发现,还有五分钟就要锁门了。被锁住出不去没饭吃饿死的话他们就要变成历史啦!!!zbt十分惊恐,把这栋楼的地图交给AiR_H,让算法大神AiR_H写个程序估计够不够时间。但是AiR_H此时很慌,所以打电话求助你让你帮他算一算至少需要多少时间才能出去。
输入描述
第一行输入一个整数n,代表这栋楼有多少层。AiR_H和zbt就在最高层。(1 <= n <= 100)
下面依次有n个地图(大小都为5 * 5),第i个地图表示第i楼的物品摆放情况
1楼的物品摆放情况
2楼的物品摆放情况
………………
n楼的物品摆放情况
说明书:
'.'代表可以行走的地方
'#'代表障碍物
'@'代表楼梯
1楼'd'字符代表出口
n楼'a'字符代表AiR_H和zbt的位置
相邻两层楼至少有一个楼梯是相同位置的,代表可以从这个位置上楼或者下楼
每个楼梯只能连接x ~ x+1楼或x ~ x-1楼
移动一格算1步,下楼梯算1步
AiR_H和zbt移动的速度为1步/秒
输入保证至少有一条可以出去的通道。
输出描述
输出一个数字代表AiR_H和zbt离开大楼至少需要多少秒。
样例输入
3 ..@#. #.#.. #...d #.#.. ..##. ..@.. #.#.# #...# ##.## @.... ..... ...#. ..a#. ####. @....样例输出
28来源
中北大学2017年程序设计新生赛
提示
从最高楼开始所花费的步数为12+1+8+1+6,共28步,所以一共花费28秒。
开始我想过用的dfs,然后,超时;
查了一些资料,才发现dfs时间复杂度高,bfs空间复杂度高,需要记录每个状态;
附上ac代码:
#include<cstdio>
#include<iostream>
#include<cmath>
#include<queue>
using namespace std;
int n;
char map[105][105][105];
int visited[105][105][105];
int dir[4][2]= {1,0,-1,0,0,1,0,-1};
struct node
{
int n;
int x;
int y;
int step;
} A;
int stn,stx,sty;
int enn,enx,eny;
int main()
{
scanf("%d",&n);
for(int i=0; i<n; i++)
{
for(int j=0; j<5; j++)
{
scanf("%s",map[i][j]);
}
}
for(int i=0; i<5; i++)
{
for(int j=0; j<5; j++)
{
if(map[0][i][j]=='d')
{
enn=0;
enx=i;
eny=j;
//printf("%d %d %d\n",enn,enx,eny);
}
}
}
for(int i=0; i<5; i++)
{
for(int j=0; j<5; j++)
{
if(map[n-1][i][j]=='a')
{
stn=n-1;
stx=i;
sty=j;
//printf("%d %d %d\n",stn,stx,sty);
}
}
}
queue<node>q;
A.n=stn;
A.x=stx;
A.y=sty;
A.step=0;
visited[A.n][A.x][A.y]=1;
q.push(A);
while(!q.empty())
{
node u=q.front();
q.pop();
if(u.x==enx&&u.y==eny&&u.n==enn)
{
printf("%d\n",u.step);
return;
}
node v;
for(int i=0; i<4; i++)
{
v.x=u.x+dir[i][0];
v.y=u.y+dir[i][1];
v.n=u.n;
if(v.n<0||v.x<0||v.x>=5||v.y<0||v.y>=5||visited[v.n][v.x][v.y]==1||map[v.n][v.x][v.y]=='#')
continue;
v.step=u.step+1;
visited[v.n][v.x][v.y]=1;
if(map[v.n][v.x][v.y]=='@')
{
v.n=u.n-1;
v.step++;
visited[v.n][v.x][v.y]=1;
}
q.push(v);
}
}
return 0;
}
bfs大致思路:
- 找到起始点与终点
- 标记起始点,起始点入队
- 判断队列是否为空,循环每个节点的子节点
- 更新队列的队首
- 判断是否到达终点
- 依次循环每个方向的点,是否超边界范围
- 更新步数,标记节点