广度优先
Description:
阿狸被困在迷宫,snoopy要去救他,snoopy可以向上、下、左、右四个方向行走,每走一步(格)就要喝掉一瓶益力多。现在给它一个迷宫地图请问:snoopy最少需要多少瓶益力多才能走出迷宫?
Input:
先输入一个数t,表示测试的数据个数, 下面输入的就是t个迷宫, 每个迷宫的输入都应包含以下数据, 输入迷宫的大小 n(n<=15),表示迷宫大小为n*n。 再输入迷宫, 用大写字母“S”表示snoopy的位置, 用小写字母“E”表示阿狸被困的位置, 用“.”表示空白, 用“*”表示障碍, 你知道的阿狸和snoopy都只有一个。
Output:
输出需要的最少的益力多的瓶数m(数据保证一定有最少需要的利益多的瓶数)
Sample Input:
2
8
S..*....
.*...**.
..*.**..
.*..*..*
*..*E.**
........
.***..*.
....*...
8
S..*....
.*...**.
.**.**..
.*..*..*
*..**.**
........
.***..*.
....*..E
Sample Output:
12
16
题意分析:这题是最简单的求最短距离的题目,也就是典型的BFS问题。
广度优先搜索:http://baike.baidu.com/view/288267.htm 如果不想看这么长的文字解释,可以看一下下面的PPT:http://www.docin.com/p-542536008.html
下面继续分析这道题目,我们挑选第二组数据进行分析。首先,我先把数据从数组下标为[1][1]的地方开始存储。让后在地图的周围“造”一堵墙(如图1)。我们还需要开一个跟地图一样大的数组visit来记录已经走过的点。将所有点初始化为0,走过的点记为1。
图1 图2 图3
然后记录S的坐标。将S入队并标记visit[s.x][s.y]=1,查看S点是否等于E,不等,将队首元素pop出去;否则返回结果。然后查看与S相邻的上下左右4点(上下左右的顺序随便),如果该点不是墙(即‘*‘)并且之前没走过(visit[该点.x][该点.y]等于0),则将该点入队,标记visit[该点.x][该点.y]=1;否则不做处理。相邻的点都查看完后,再取队首元素查看该点是否等于E.......(重复做绿色部分的步骤,直到队列为空)。为了便于理解,上面贴出了图2和图3。图中的数字即为第n步到达的位置。
下面贴出源代码:
1 #include<cstdio> 2 #include<cstring> 3 #include<queue> 4 using namespace std; 5 char map[17][17];//地图 6 bool visit[17][17];//用来记录状态 7 int dir[][2]={{1,0},{0,1},{-1,0},{0,-1}};//方向 8 struct Point 9 { //记录点的坐标和步数 10 int x,y,cnt; 11 }; 12 void BFS(int sx,int sy) 13 { 14 queue<Point> a; 15 Point now,next; 16 now.x = sx; now.y = sy; now.cnt = 0; 17 a.push(now); 18 visit[sx][sy] = 1; 19 while(!a.empty()) 20 { 21 Point temp = a.front(); a.pop(); 22 if(map[temp.x][temp.y] == ‘E‘) 23 { 24 printf("%d\n",temp.cnt); 25 return ; 26 } 27 for(int i = 0; i < 4; i++) 28 { 29 next.x = temp.x+dir[i][0]; 30 next.y = temp.y+dir[i][1]; 31 next.cnt = temp.cnt+1; 32 if((!visit[next.x][next.y]) && (map[next.x][next.y]!=‘*‘)) 33 { a.push(next); visit[next.x][next.y] = 1;} 34 } 35 } 36 return ; 37 } 38 int main(void) 39 { 40 int i,j,t,m,n; 41 scanf("%d",&t); 42 while(t--) 43 { 44 int sx,sy; 45 memset(visit,0,sizeof(visit)); 46 scanf("%d",&n); 47 for(i = 1; i <= n; i++) 48 scanf("%s",&map[i][1]); 49 for(i = 0; i <= (n+1); i++) 50 for(j = 0; j <= (n+1); j++) 51 { 52 if(map[i][j] == ‘S‘) 53 sx = i, sy = j; 54 if((i==0) || (j==0) || (i==n+1) || (j==n+1)) 55 map[i][j] = ‘*‘; 56 } 57 BFS(sx,sy); 58 } 59 60 return 0; 61 }
这是我做的第一道搜索题,做了一下午,才真正搞懂BFS。以前也一直不会BFS,看别人的代码都好长,有的又看不懂。还是上面红色链接里的PPT帮了大忙,不懂的多看几次PPT。下面是我做的PPT也可以看看:http://files.cnblogs.com/files/Muia/%E8%BF%B7%E5%AE%AB.ppt