🧱 迷宫 BFS 四大组装模块
-
模块一:读图与侦察(找起点)
-
动作 :两个
for循环读入地图。 -
核心细节 :看到
'S'立刻把坐标记下来,顺手把dist数组全部刷成-1(清空案发现场)。
-
-
模块二:点火起步(发准考证)
-
动作 :建队列
queue<pair<int, int>>,把起点塞进去。 -
致命细节 :千万别忘了
dist[sx][sy] = 0。起跑前必须给起点挂上 0 步的牌子!
-
-
模块三:十字雷达扫描(核心引擎)
-
动作 :
while循环里套一个 4 次的for循环(利用dx, dy数组)。 -
核心细节 :极其严密的"四重防弹衣"------
nx, ny不能越界、不能撞墙 (#)、不能去过 (dist != -1)。一旦发现'E',立刻记录步数并强行刹车(break)。
-
-
模块四:清算离场
- 动作 :输出答案。没找到就老老实实输出
-1。
- 动作 :输出答案。没找到就老老实实输出
迷宫
题目描述
Time Limit: 1000 ms
Memory Limit: 256 mb
小 A 同学现在被困在了一个迷宫里面,他很想从迷宫中走出来,他可以 向上、向下、向左、向右移动、每移动一格都需要花费 1 秒的时间,不能够走到 边界之外。假设小 A 现在的位置在 S,迷宫的出口在 E,迷宫可能有多个出口。 问小 A 想要走到迷宫出口最少需要花费多少秒?
输入输出格式
输入描述:
有多组测试数据。 第一行输入两个正整数 H(0 < H <= 100)和 W(0 < W <= 100),分别表示迷 宫的高和宽。 接下来 H 行,每行 W 个字符(其中'*'表示路,'#'表示墙,'S'表示小 A 的位置,'E'表示迷宫出口)。 当 H 与 W 都等于 0 时程序结束。
输出描述:
输出小 A 走到迷宫出口最少需要花费多少秒,如果永远无法走到出口则输出"-1"。
输入输出样例
输入样例#:
复制
3 3
S*#
**#
#*E
0 0
输出样例#:
复制
4
题目来源
天津大学/南开大学机试题
#include<bits/stdc++.h>
using namespace std;
char g[105][105];
int dist[105][105];
int dx[4] = {1, -1, 0, 0};
int dy[4] = {0, 0, 1, -1};
int main() {
int h, w;
while(cin>>h>>w){
if(h == 0 && w == 0){
break;
}
int sx = -1, sy = -1;
for(int i = 0; i < h; i ++){//分清行列, 高是有几行, 宽是有几列
for(int j = 0; j < w; j ++){
dist[i][j] = -1;//刚开始都标记为没走过
cin>>g[i][j];//输入迷宫
if(g[i][j] == 'S'){//初始位置
sx = i;
sy = j;
}
}
}
queue<pair<int, int>> q;
q.push({sx, sy});
bool found = false;//是否找到了?
dist[sx][sy] = 0;
while(!q.empty()){
if(found){
break;
}
auto i = q.front();//当前位置
q.pop();
int x = i.first;
int y = i.second;
for(int k = 0; k < 4; k ++){
int nx = x + dx[k];
int ny = y + dy[k];
if(nx < 0 || nx >= h || ny < 0 || ny >= w){//越界
continue;
}
if(g[nx][ny] == '#'){//撞墙
continue;
}
if(dist[nx][ny] != -1){//访问过
continue;
}
if(g[nx][ny] == 'E'){//终点
cout<<dist[x][y] + 1<<endl;
found = true;
break;
}
dist[nx][ny] = dist[x][y] + 1;
q.push({nx, ny});
}
}
if(found == false){//没找到
cout<<"-1"<<endl;
}
}
}
机器人走迷宫
机器人走迷宫
题目描述
Time Limit: 1000 ms
Memory Limit: 256 mb
有一个愚蠢的机器人走进一个w*h的迷宫,迷宫里有空地和陷阱。他想要访问迷宫的每个方格,但是它很笨,只会按照指令的方向走。当机器人不能走的时候,也就是下一步会遇到陷阱、迷宫边界或者访问过的格子,它会向右转90度(顺时针旋转90度,不能访问已经访问过的方格,且在原地只转一次,移动后可获得又一次旋转机会)。请问这个机器人最多可以经过多少个方格。
例如:
5 5
R....
.....
.....
.....
.....
机器人可以经过25个格子,但是
2 3
..L
...
机器人只能经过3个格子。
输入输出格式
输入描述:
对于每组数据,第一行两个数w和h,表示迷宫的行和列(1<=w,h<=10) 接下来w行每行有h个字符用于描述这个迷宫。迷宫的'.'表示空地,即为可以走的地方。'*'表示陷阱,即为不能走的地方。迷宫中有一个英文字母,表示机器人的出发点,字母只有'U','D','L','R'四种。分别表示机器人的初始指令是向上,向下,向左,向右。
输出描述:
对于每组数据,输出一个整数,即机器人一共经过多少个方格。
输入输出样例
输入样例#:
复制
2 3
U..
.*.
4 4
R...
.**.
.**.
....
输出样例#:
复制
4
12
题目来源
中南大学/中山大学机试题
#include<bits/stdc++.h>
using namespace std;
#define N 20
char g[N][N];//数组大小注意!!!
int dist[N][N];//拿 int 的碗去接 char 的饭
int dx[4] = {-1, 0, 1, 0};//上右下左
int dy[4] = {0, 1, 0, -1};
bool canPass(int nx, int ny, int w, int h){
if(nx < 0 || nx >= w || ny < 0 || ny >= h){//边界
return false;
}
if(g[nx][ny] == '*'){//陷阱
return false;
}
if(dist[nx][ny] != -1){//访问过
return false;
}
return true;
}
int main(){
int w, h;
while(cin>>w>>h){
int sx = -1, sy = -1, dir = -1;//初始信息
for(int i = 0; i < w; i ++){
for(int j = 0; j < h; j ++){
dist[i][j] = -1;//初始化为-1
cin>>g[i][j];
if(g[i][j] == 'U'){//上
sx = i;
sy = j;
dir = 0;
}
if(g[i][j] == 'R'){//初始方向右
sx = i;
sy = j;
dir = 1;
}
if(g[i][j] == 'D'){//初始方向下
sx = i;
sy = j;
dir = 2;
}
if(g[i][j] == 'L'){//初始方向左
sx = i;
sy = j;
dir = 3;
}
}
}//
dist[sx][sy] = 1;//初始化
int count = 1;//起点以访问
while(true){//开始模拟
int nx = sx + dx[dir];
int ny = sy + dy[dir];
if(canPass(nx, ny, w, h)){//能走
dist[nx][ny] = 1;//更新
sx = nx;
sy = ny;
count ++;
continue;
}
int ndir = (dir + 1) % 4;//不能走就右转
nx = sx + dx[ndir];
ny = sy + dy[ndir];
if(canPass(nx, ny, w, h)){//嫩个走了
dir = ndir;//记得更新方向
dist[nx][ny] = 1;//更新
sx = nx;
sy = ny;
count ++;
continue;
}
break;//还是走不了
}
cout<<count<<endl;
}
}