迷宫c++(详解)

题目描述

本题为填空题,只需要算出结果后,在代码中使用输出语句将所填结果输出即可。

下图给出了一个迷宫的平面图,其中标记为 11 的为障碍,标记为 00 的为可以通行的地方。

010000
000100
001001
110000

迷宫的入口为左上角,出口为右下角,在迷宫中,只能从一个位置走到这 个它的上、下、左、右四个方向之一。

对于上面的迷宫,从入口开始,可以按 DRRURRDDDR 的顺序通过迷宫, 一共 1010 步。其中 D、U、L、RDULR 分别表示向下、向上、向左、向右走。 对于下面这个更复杂的迷宫(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;
}
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值