题目描述
本题为填空题,只需要算出结果后,在代码中使用输出语句将所填结果输出即可。
下图给出了一个迷宫的平面图,其中标记为 11 的为障碍,标记为 00 的为可以通行的地方。
010000
000100
001001
110000迷宫的入口为左上角,出口为右下角,在迷宫中,只能从一个位置走到这 个它的上、下、左、右四个方向之一。
对于上面的迷宫,从入口开始,可以按 DRRURRDDDR 的顺序通过迷宫, 一共 1010 步。其中 D、U、L、RD、U、L、R 分别表示向下、向上、向左、向右走。 对于下面这个更复杂的迷宫(3030 行 5050 列),请找出一种通过迷宫的方式,其使用的步数最少,在步数最少的前提下,请找出字典序最小的一个作为答案。
请注意在字典序中 D<L<R<UD<L<R<U。
01010101001011001001010110010110100100001000101010
00001000100000101010010000100000001001100110100101
01111011010010001000001101001011100011000000010000
01000000001010100011010000101000001010101011001011
00011111000000101000010010100010100000101100000000
11001000110101000010101100011010011010101011110111
00011011010101001001001010000001000101001110000000
10100000101000100110101010111110011000010000111010
00111000001010100001100010000001000101001100001001
11000110100001110010001001010101010101010001101000
00010000100100000101001010101110100010101010000101
11100100101001001000010000010101010100100100010100
00000010000000101011001111010001100000101010100011
10101010011100001000011000010110011110110100001000
10101010100001101010100101000010100000111011101001
10000000101100010000101100101101001011100000000100
10101001000000010100100001000100000100011110101001
00101001010101101001010100011010101101110000110101
11001010000100001100000010100101000001000111000010
00001000110000110101101000000100101001001000011101
10100101000101000000001110110010110101101010100001
00101000010000110101010000100010001001000100010101
10100001000110010001000010101001010101011111010010
00000100101000000110010100101001000001000000000010
11010000001001110111001001000011101001011011101000
00000110100010001000100000001000011101000000110011
10101000101000100010001111100010101001010000001000
10000010100101001010110000000100101010001011101000
00111100001000010000000110111000000001000000001011
10000001100111010111010001000110111010101101111000运行限制
最大运行时间:1s
最大运行内存: 256M
一开始的题解,先从0开始还是从1看个人习惯
#include<bits/stdc++.h>
using namespace std;
char wz[50][55];
char d[4] = { 'D','L','R','U' };
// char dir[4][2]={{-1,0},{0,-1},{0,1},{1,0}};err
// char dir[4][2] = { {1,0},{0,-1},{0,1},{-1,0} };err
int dir[4][2] = { {1,0},{0,-1},{0,1},{-1,0} };
//这是数字不是字符,真的醉了
//你写的时候要知道你在干什么才行,不要乱贴标签
//往上走是相当于减一行,往下走是加一行!
struct node
{
int x;
int y;
string s;
};
void bfs()
{
//哪个node 哪个信息一定要指清楚!
node next, now;
queue<node>que;
// wz[1][1]="1";err
wz[1][1] = '1';
//字符串用"",字符用''
now.s = "";// s="";err麻烦你清楚是那个位置的s
now.x = now.y = 1;
que.push(now);
//用条件与初始化条件分隔
while (!que.empty())
{
now = que.front();
que.pop();
if (now.x == 30 && now.y == 50)
{
// cout<<now<<endl;err
cout << now.s << endl;
//请指定你要输出什么!
}
for (int i = 0; i < 4; i++)
{
next.x = now.x + dir[i][0];
next.y = now.y + dir[i][1];
//下标的移动
// if(next.x>0&&next.x<=30&&next.y>0&&next.y<=50&&wz[next.x][next.y]=0)err
if (next.x > 0 && next.x <= 30 && next.y > 0 && next.y <= 50 && wz[next.x][next.y] == '0')
//是字符不是数字,还有是等价不是赋值
{
// wz[next.x][next.y]=1;err
wz[next.x][next.y] = '1';
//是字符不是数字
next.s = now.s + d[i];
que.push(next);
}
}
}
}
int main()
{
for (int i = 1; i <=30; i++)
for (int j = 1; j <=50; j++)
{
// scanf("%s",&wz[i][j]);err
//c语言的坏毛病,写scanf是错误输出,也不知道为啥可以通过编译器
cin>>wz[i][j];
}
bfs();
return 0;
}
既然只有1和0,我就想可不可以用int数组来实现,然后答案错了。但最后我明白是网站上的sb编译器有问题,害得我想半天为什么不行.用int数组输入数据的输出是错的,只能用char才正确。如果非要用也行,就是自己手动插入数据。
不过最好确实也是用char,因为万一是字符如a,b这种,显然char更通用一些,char同样也能把数字当成字符,因此一般的地图还是bfs最好还是用char。
补充,填空题编译器答案可能会出问题,所以说直接在自己的编译器输出结果直接打印是最好的
#include <iostream>
#include <algorithm>
#include <string>
#include <string.h>
#include <queue>
///BFS+字符串
using namespace std;
#define maxn 50
int maze[maxn][maxn];
char d[4] = { 'D','L','R','U' };//注意,这里要按照字典序顺序排
int dir[4][2] = { {1,0},{0,-1},{0,1},{-1,0} };//这里的顺序要和上面d数组一一对应
int n=4, m=6;
struct node
{
int x;
int y;
string s;
/* data */
};
//每一次的循环都是只有一步,而且每轮都是要判断是否到达终点,
//因此也一定是最少步数,只要有点到了就会立马返回,典序一直都在判断,
//所以根本就不需要考虑步数最少,队列输出一定是最优解
//而且每一次都是从队尾,插入也有顺序,因此一定是最小的在最前面
void bfs()
{
node now, next;
queue<node> que;
//默认队尾添加,队头删除
//队列
maze[0][0] = 1;
now.s = "";
now.x = now.y = 0;
que.push(now);
while (!que.empty())
{
now = que.front();
//这里的now读取了数据,起到继承上一次的作用
//给结点赋值
que.pop();
if (now.x == n - 1 && now.y == m - 1)
//走到终点
//从一开始的00一直到出口
//n-1是因为从0开始插入
{
cout << now.s << endl;
}
for (int i = 0; i < 4; i++)
{
next.x = now.x + dir[i][0];
next.y = now.y + dir[i][1];
//行移动上下,列移动左右,相当于移动位置
//确实只有这样才能移动
// 行才能改变上下,列改变左右
//改变行数和列数,等于移动坐标
//每一轮都分别有上下左右的移动方式
if (next.x >= 0 && next.x < n && next.y >= 0 && next.y < m && maze[next.x][next.y] == 0)
//如果进不来这个条件,就自动读取不了next的记录,就直接完全删除了,就相当于无路可走,就退出了
{
maze[next.x][next.y] = 1;//记录走过
next.s = now.s + d[i];
//记录每种可能的字符串
que.push(next);//队尾插入等待now继续向前探索
}
}
}
}
//总的来说就是搜索,每一步讨论所有可能移动的方向,一个字符串保留数据。
//与循环不同就在于,每一轮都会删除上一次的结果,而合法数据得到继承,不合法就永久删除
int main()
{
for (int i = 0; i < n; i++)
{
for (int j = 0; j < m; j++)
{
cin >> maze[i][j];
}
}
//这么写没问题的,你直接输入,即使存在数据,系统会帮你自动填写的
//所以这是通用的
bfs();
return 0;
}


下面是最终版本和解析,从0开始就是写起来方便一些,但是要注意判断末尾是n-1&&m-1
然后就是通用性,把30和50改为n,m放在全局,这样只用改变n,m的大小就能实现不同大小迷宫
的输出,另外还能够直接插入n与m,十分泛用.
///BFS+字符串
#include<bits/stdc++.h>
using namespace std;
#define maxn 50
char maze[maxn][maxn];
char d[4] = { 'D','L','R','U' };//注意,这里要按照字典序顺序排
int dir[4][2] = { {1,0},{0,-1},{0,1},{-1,0} };//这里的顺序要和上面d数组一一对应
int n = 30, m = 50;
struct node
{
int x;
int y;
string s;
/* data */
};
//每一次的循环都是只有一步,而且每轮都是要判断是否到达终点,
//因此也一定是最少步数,只要有点到了就会立马返回,典序一直都在判断,
//所以根本就不需要考虑步数最少,队列输出一定是最优解
//而且每一次都是从队尾,插入也有顺序,因此一定是最小的在最前面
void bfs()
{
node now, next;
queue<node> que;
//默认队尾添加,队头删除
//队列
maze[0][0] = '1';
now.s = "";
now.x = now.y = 0;
que.push(now);
while (!que.empty())
{
now = que.front();
//这里的now读取了数据,起到继承上一次的作用
//给结点赋值
que.pop();
if (now.x == n - 1 && now.y == m - 1)
//走到终点
//从一开始的00一直到出口
//n-1是因为从0开始插入
{
cout << now.s << endl;
}
for (int i = 0; i < 4; i++)
{
next.x = now.x + dir[i][0];
next.y = now.y + dir[i][1];
//行移动上下,列移动左右,相当于移动位置
//确实只有这样才能移动
// 行才能改变上下,列改变左右
//改变行数和列数,等于移动坐标
//每一轮都分别有上下左右的移动方式
if (next.x >= 0 && next.x < n && next.y >= 0 && next.y < m && maze[next.x][next.y] == '0')
//如果进不来这个条件,就自动读取不了next的记录,就直接完全删除了,就相当于无路可走,就退出了
{
maze[next.x][next.y] = '1';//记录走过
next.s = now.s + d[i];
//记录每种可能的字符串
que.push(next);//队尾插入等待now继续向前探索
}
}
}
}
//总的来说就是搜索,每一步讨论所有可能移动的方向,一个字符串保留数据。
//与循环不同就在于,每一轮都会删除上一次的结果,而合法数据得到继承,不合法就永久删除
int main()
{
//cin >> n >> m;根据需要来写
for (int i = 0; i < n; i++)
{
for (int j = 0; j < m; j++)
{
cin >> maze[i][j];
}
}
//这么写没问题的,你直接输入,即使存在数据,系统会帮你自动填写的
//所以这是通用的
bfs();
return 0;
}
文章介绍了如何利用广度优先搜索(BFS)算法解决迷宫问题,找到从起点到终点的最短步数和字典序最小的路径。通过创建一个节点结构,存储当前位置和路径字符串,并使用字符数组表示移动方向,确保字典序的正确性。在遍历过程中,更新迷宫矩阵以避免重复访问,并在找到出口时输出路径字符串。

4764

被折叠的 条评论
为什么被折叠?



