仙岛求药
【题目描述】
李逍遥闯进了仙灵岛,克服了千险万难来到岛的中心,发现仙药摆在了迷阵的深处。迷阵由M*N个方格组成,有的方格内有可以瞬秒李逍遥的怪物,而有的方格内则是安全。现在李逍遥想尽快找到仙药,显然他应避开有怪物的方格,并经过最少的方格。现在要求你来帮助他实现这个目标。
下图显示了一个迷阵的样例及李逍遥找到仙药的路线。
【输入描述】
输入有多组测试数据。每组测试数据以两个非零整数M和N开始,两者均不大于20。M表示迷阵行数,N表示迷阵列数。接下来有M行,每行包含N个字符,不同字符分别代表不同含义:
(1) ‘@’ :少年李逍遥所在的位置;
(2) ‘.’ :可以安全通行的方格;
(3) ‘#’ :有怪物的方格;
(4) ‘*’ :仙药所在位置。
当一行中读入的是两个零时,表示输入结束。
【输出描述】
对于每组测试数据,分别输出一行,该行包含李逍遥找到仙药需要穿过的最少的方格数目(计数包括初始位置的方块)。如果他不可能找到仙药,则输出-1。
【输入样例】
8 8
.@##...#
#....#.#
#.#.##..
..#.###.
#.#...#.
..###.#.
...#.*..
.#...###
6 5
.*.#.
.#...
..##.
.....
.#...
....@
9 6
.#..#.
.#.*.#
.####.
..#...
..#...
..#...
..#...
#.@.##
.#..#.
0 0
【输出样例】
10
8
-1
源代码: #include<iostream> #include<cstring> using namespace std; char Map[101][101]; //Map[]记录地图字符。 int m,n,i[101][101],ans=0; //i[]记录走到某一位置的最少步数。 void BFS(int x1,int y1,int x2,int y2) //此广搜的妙处在于将最短路更新与去重结合在了一起,步数多的自然不会去更新步数少的。 { int t=i[x1][y1]; if (x1==x2&&y1==y2) //到达目的地。 ans=t; t++; if (y1<m-1&&Map[x1][y1+1]!='#'&&i[x1][y1+1]>t) //右移。 { i[x1][y1+1]=t; BFS(x1,y1+1,x2,y2); } if (x1>0&&Map[x1-1][y1]!='#'&&i[x1-1][y1]>t) //上移。 { i[x1-1][y1]=t; BFS(x1-1,y1,x2,y2); } if (y1>0&&Map[x1][y1-1]!='#'&&i[x1][y1-1]>t) //左移。 { i[x1][y1-1]=t; BFS(x1,y1-1,x2,y2); } if (x1<n-1&&Map[x1+1][y1]!='#'&&i[x1+1][y1]>t) //下移。 { i[x1+1][y1]=t; BFS(x1+1,y1,x2,y2); } } int main() { int x1,y1,x2,y2; while (cin>>n>>m&&m!=0&&n!=0) { for (int a=0;a<n;a++) //以0为边界开始。 { for (int b=0;b<m;b++) { cin>>Map[a][b]; if (Map[a][b]=='@') { x1=a; y1=b; } if (Map[a][b]=='*') { x2=a; y2=b; } } } memset(i,0x3f,sizeof(i)); //赋最大值来辨认是否走过以及避免重复。 i[x1][y1]=0; BFS(x1,y1,x2,y2); if (ans!=0) cout<<ans<<endl; else cout<<-1<<endl; ans=0; } return 0; }