1251:仙岛求药
时间限制: 1000 ms 内存限制: 65536 KB
提交数: 25309 通过数: 11182
【题目描述】
少年李逍遥的婶婶病了,王小虎介绍他去一趟仙灵岛,向仙女姐姐要仙丹救婶婶。叛逆但孝顺的李逍遥闯进了仙灵岛,克服了千险万难来到岛的中心,发现仙药摆在了迷阵的深处。迷阵由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<bits/stdc++.h>
using namespace std;
struct Node
{
int x, y, s;//从起点走到(x,y)位置时已经走了s步
Node(){}
Node(int a, int b, int c):x(a), y(b), s(c) {}
};
int dir[4][2] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};//方向数组
char mp[25][25];//地图
bool vis[25][25];//vis[i][j]:(i,j)位置是否已访问
int m, n, sx, sy;//(sx, sy):起点
int bfs(){//广搜求从起点到终点的最短距离
queue<Node> que;
vis[sx][sy] = true;
que.push(Node(sx, sy, 0));//起点入队,在起点时步数为0
while(que.empty() == false){
Node u = que.front();
que.pop();
if(mp[u.x][u.y] == '*'){//如果该位置是终点
return u.s;//输出到终点时的步数
}
for(int i = 0; i < 4; ++i){
int x = u.x + dir[i][0];
int y = u.y + dir[i][1];
int s = u.s + 1;
if(x >= 1 && x <= m && y >= 1 && y <= n && mp[x][y] != '#' &&
vis[x][y] == false){
//如果(x,y)在地图内,不是墙,没访问过
vis[x][y] = true;//访问该位置
que.push(Node(x, y, s));//到(x,y)时步数为s,入队
}
}
}
return -1;//如果无法到达终点,则会运行到这里,返回-1
}
int main(){
while(cin >> m >> n){
if(m == 0 && n == 0){
break;
}
for(int i = 1; i <= m; ++i){
for(int j = 1; j <= n; ++j){
cin >> mp[i][j];
if(mp[i][j] == '@')
sx = i;
sy = j;
}
}
memset(vis, 0, sizeof(vis));//多组数据,注意数据清零
cout << bfs() << endl;
}
return 0;
}
1252:走迷宫
时间限制: 1000 ms 内存限制: 65536 KB
提交数: 29294 通过数: 13590
【题目描述】
一个迷宫由R行C列格子组成,有的格子里有障碍物,不能走;有的格子是空地,可以走。
给定一个迷宫,求从左上角走到右下角最少需要走多少步(数据保证一定能走到)。只能在水平方向或垂直方向走,不能斜着走。
【输入】
第一行是两个整数,R和C,代表迷宫的长和宽。( 1<= R,C <= 40)
接下来是R行,每行C个字符,代表整个迷宫。
空地格子用‘.’表示,有障碍物的格子用‘#’表示。
迷宫左上角和右下角都是‘.’。
【输出】
输出从左上角走到右下角至少要经过多少步(即至少要经过多少个空地格子)。计算步数要包括起点和终点。
【输入样例】
5 5 ..### #.... #.#.# #.#.# #.#..
【输出样例】
9
【代码示例】
#include <bits/stdc++.h>
using namespace std;
#define N 45
struct Node{//设置结点
int x, y, s;//到(x,y)位置是步数为s
Node(){}
Node(int a, int b, int c):x(a), y(b), s(c){}
};
int r, c;//行、列
char mp[N][N];//地图
bool vis[N][N];//vis[i][j]表示第i,j位置是否已访问过
int dir[4][2] = {{-1, 0}, {1, 0}, {0, 1}, {0, -1}}; //方向数组
int bfs(){//广搜,返回从左上角走到右下角的最少步数
queue<Node> que;
vis[1][1] = true;//访问初始位置
que.push(Node(1, 1, 1));
while(que.empty() == false){//如果队列不空
Node u = que.front();
que.pop();//出队一个结点
if(u.x== r && u.y == c){//如果到终点
return u.s;//返回终点结点上的步数
}
for(int i = 0; i < 4; ++i){//遍历四个方向上的位置
int x = u.x + dir[i][0], y = u.y + dir[i][1], s = u.s + 1;
//新的位置,以及步数
if(x >= 1 && x <= r && y >= 1 && y <= c && vis[x][y] == false
&& mp[x][y] == '.'){//如果在范围内 且 没访问过 且 这个位置是空地
vis[x][y] = true;//访问x,y位置
que.push(Node(x, y, s));//该位置及步数构成结点,入队
}
}
}
}
int main(){
cin >> r >> c;
for(int i = 1; i <= r; ++i){
for(int j = 1; j <= c; ++j){
cin >> mp[i][j];
}
}
cout << bfs();
return 0;
}
1255:迷宫问题
时间限制: 1000 ms 内存限制: 65536 KB
提交数: 17082 通过数: 8070
【题目描述】
定义一个二维数组:
int maze[5][5] = { 0,1,0,0,0, 0,1,0,1,0, 0,0,0,0,0, 0,1,1,1,0, 0,0,0,1,0, };
它表示一个迷宫,其中的1表示墙壁,0表示可以走的路,只能横着走或竖着走,不能斜着走,要求编程序找出从左上角到右下角的最短路线。
【输入】
一个5 × 5的二维数组,表示一个迷宫。数据保证有唯一解。
【输出】
左上角到右下角的最短路径,格式如样例所示。
【输入样例】
0 1 0 0 0 0 1 0 1 0 0 0 0 0 0 0 1 1 1 0 0 0 0 1 0
【输出样例】
(0, 0) (1, 0) (2, 0) (2, 1) (2, 2) (2, 3) (2, 4) (3, 4) (4, 4)
【代码示例】
#include <bits/stdc++.h>
using namespace std;
#define N 1001
struct Node{
int x, y, s;//走到(x,y)时步数为s
Node(){}
Node(int a, int b, int c):x(a),y(b),s(c){}
};
int n, m, dir[4][2] = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};//dir:方向数组
char mp[N][N];//地图
bool vis[N][N];//vis[i][j]:第i,j位置是否已访问过
int bfs(int stx, int sty){//以(stx, sty)为起点进行广搜
queue<Node> que;
vis[stx][sty] = true;//起始点先访问再入队
que.push(Node(stx, sty, 0));
while(que.empty() == false){
Node u = que.front();
que.pop();
if(mp[u.x][u.y] == 'T'){//如果到终点
return u.s;
}
for(int i = 0; i < 4; ++i){
int x = u.x + dir[i][0], y = u.y + dir[i][1], s = u.s + 1;//(x,y)新位置
if(x >= 1 && x <= n && y >= 1 && y <= m && vis[x][y] == false && mp[x][y] != '#'){
//如果新位置在地图内,没访问过,不是墙
vis[x][y] = true;
que.push(Node(x, y, s));
}
}
}
}
int main(){
int stx, sty;
cin >> n >> m;
for(int i = 1; i <= n; ++i){
for(int j = 1; j <= m; ++j){
cin >> mp[i][j];
if(mp[i][j] == 'S'){//记录起点位置
stx = i;
sty = j;
}
}
}
cout << bfs(stx, sty) << endl;
return 0;
}