当前位置:首页 > 题解目录 > 正文内容

【题解】走出迷宫的最少步数

亿万年的星光1年前 (2025-02-08)题解目录1385

【题目描述】

一个迷宫由R行C列格子组成,有的格子里有障碍物,不能走;有的格子是空地,可以走。

给定一个迷宫,求从左上角走到右下角最少需要走多少步(数据保证一定能走到)。只能在水平方向或垂直方向走,不能斜着走。

【输入描述】

第一行是两个整数,R和C,代表迷宫的行数和列数。( 1<= R,C <= 40)

接下来是R行,每行C个字符,代表整个迷宫。空地格子用’.‘表示,有障碍物的格子用’#‘表示。迷宫左上角和右下角都是’.’。

【输出描述】

输出从左上角走到右下角至少要经过多少步(即至少要经过多少个空地格子)。计算步数要包括起点和终点。

【样例输入】

5 5
..###
#....
#.#.#
#.#.#
#.#..

【样例输出】

9

【题目分析】

BFS样例题目


80分版本(超时)

#include<bits/stdc++.h>
using namespace std;
char Map[45][45];
int dir[4][2]={1,0,-1,0,0,-1,0,1};
int n,m,ans;
struct node{
	int x,y,step;
}now,nextt;
queue<node> q;
int BFS(int x,int y){
	int xx,yy,zz;
	Map[x][y]='6';
	now.x=x;
	now.y=y;
	now.step=0;
	q.push(now);
	while(!q.empty()){
		now=q.front();
		q.pop();
		for(int i=0;i<4;i++){
			xx=now.x+dir[i][0];
			yy=now.y+dir[i][1];
			if(xx>=1&&xx<=n&&yy>=1&&yy<=m&&Map[xx][yy]!='#'&&Map[xx][yy]!='6'){
				nextt.x=xx;
				nextt.y=yy;
				nextt.step=now.step+1;
				Map[now.x][now.y]='6';
				if(Map[xx][yy]=='9'){
					return nextt.step;
				}
				q.push(nextt);
			}
		}
	}
	return -1;
}
int main(){
    cin>>n>>m;
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			cin>>Map[i][j];
		}
	}
	Map[n][m]='9';
	ans=BFS(1,1);
	cout<<ans+1;
	return 0;
}



100分版本:

#include<bits/stdc++.h>
using namespace std;
char Map[45][45]; // 存储迷宫
bool visited[45][45]; // 记录访问状态
int dir[4][2] = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}}; // 四个方向
int n, m;
struct node {
    int x, y, step;
}now,nextt;
queue<node> q; //队列 
int BFS(int startX, int startY) {
    now.x=startX;
    now.y=startY;
    now.step=1;
	q.push(now); // 起点步数为 1
    visited[startX][startY] = true; //标记 
    while (!q.empty()) {
        node now = q.front();
        q.pop();
        // 到达终点
        if (now.x == n && now.y == m) {
            return now.step;
        }
        // 遍历四个方向
        for (int i = 0; i < 4; i++) {
            int xx = now.x + dir[i][0];
            int yy = now.y + dir[i][1];
            // 检查边界和访问状态
            if (xx >= 1 && xx <= n && yy >= 1 && yy <= m && Map[xx][yy] == '.' && !visited[xx][yy]) {
                visited[xx][yy] = true; // 标记为已访问
                nextt.x=xx;
				nextt.y=yy;
				nextt.step=now.step+1;
				q.push(nextt);
            }
        }
    }
    return -1; // 如果没有找到路径(题目保证一定有路径)
}

int main() {
    cin >> n >> m;
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= m; j++) {
            cin >> Map[i][j];
        }
    }

    // 初始化访问数组
    memset(visited, false, sizeof(visited));

    // 起点是 (1, 1),终点是 (n, m)
    int ans = BFS(1, 1);
    cout << ans << endl;

    return 0;
}





优化操作:

1. 优化访问标记

在原代码中,使用 Map[xx][yy]='6' 来标记访问过的节点。这种方法会修改地图数据,可能导致不必要的麻烦。建议使用一个独立的二维数组 visited 来记录访问状态。

2. 提前终止

当找到终点时,直接返回结果,避免继续搜索。

3. 减少不必要的操作

在每次循环中,Map[now.x][now.y]='6' 的操作是不必要的,因为当前节点已经在队列中,不需要重复标记。

4. 优化队列操作

使用 queue 时,尽量避免频繁的入队和出队操作。可以通过优化条件判断来减少不必要的入队。






    扫描二维码推送至手机访问。

    版权声明:本文由青少年编程知识记录发布,如需转载请注明出处。

    分享给朋友:

    相关文章

    【题解】东哥的杯子

    【题解】东哥的杯子

    【题目描述】话说在一场牛客练习赛中,东哥力压群雄,挣得第一,牛客为了奖励东哥的发挥,送他一个马克杯。奖励的马克杯是一个标准的圆台形状,它的上底为R1,下底为R2,高为H, 东哥向杯子里倒V毫升的水,你...

    【题解】摘花生问题

    【题解】摘花生问题

    【题目描述】Hello Kitty想摘点花生送给她喜欢的米老鼠。她来到一片有网格状道路的矩形花生地(如下图),从西北角进去,东南角出来。地里每个道路的交叉点上都有种着一株花生苗,上面有若干颗花生,经过...

    【题解】母牛的故事

    【题解】母牛的故事

    【题目描述】有一头母牛,它每年年初生一头小母牛。每头小母牛从第四个年头开始,每年年初也生一头小母牛。请编程实现在第n年的时候,共有多少头母牛?【输入描述】输入数据由多个测试实例组成,每个测试实例占一行...

    【题解】背包问题3

    【题目描述】完全背包定义有N种物品和一个容量为V的背包,每种物品都有无限件可用。第i种物品的体积是c,价值是w。求解将哪些物品装入背包可使这些物品的体积总和不超过背包容量,且价值总和最大。本题要求是背...

    进制转换(1)

    【题目描述】毛毛是个健忘的孩子,编程课上老师刚讲过进制转换的问题,她又忘了。请你帮他编写一个程序,完成一个浮点数与二进制之间的相互转换【输入描述】两个数字,第一个数字表示要转换的数字,浮点型。第二个是...

    【题解】吃糖果

    【题解】吃糖果

    【题目描述】小明终于从小红手里赢走了所有的糖果,小明转变吃掉所有糖果,但是小明吃糖果有个特殊癖好,就是不喜欢将一样的糖果放在一起吃,喜欢先吃一种,下一次吃另外一种。试问小明是否存在一种吃糖果的顺序使得...