zoukankan      html  css  js  c++  java
  • 信息学奥赛一本通网站1255 迷宫问题 题解

    今天做了一道广搜题目[我是传送门],还是老套的迷宫问题.

    但是这个是需要记录路径,我之前也听说过这种题目,不过这是第一次做.

    其实我一开始想了很长时间,想了很多实现不了的思路,不过我翻课本的时候

    算了,不"虚伪"了,直接进入正题:

    和普通的迷宫问题唯一的区别的需要记录路径,基本相当于"升级",我们可以定义一个数组pre[]来记录前驱或后继(本体显然是后继)

    但本蒟蒻一开始想错了,写成了前驱,但是我很聪(lan)明(duo),写了一个stack,又倒过来一遍,大家凑活着看吧(大家看明白后可以自己写后继):

    #include<bits/stdc++.h>
    using namespace std;
    int tot[5][5];
    struct P {//定义结构体,因为是二维的,所以需要一个x一个y
        int x;//前驱横坐标
        int y;//前驱纵坐标
    };
    P pre[5][5];int xx[5] = {0,-1,0,0,1},yy[5] = {0,0,-1,1,0 };//神奇的东西,一会就明白(之前用过的话当我没说)
    int a[5][5];//二维空间
    queue<int>q;//广搜用的队列
    stack <int> s;//偷懒用的栈
    void print(int x2,int y2) {//打印
        if(x2 == 0 && y2 == 0) {//如果存完了
            while(s.empty() == 0) {//开始弹出
                int a = s.top();//一定要定义一个a不然会反过来(写前驱的话)
                s.pop();
                cout<<"("<<s.top()<<", ";
                s.pop();
                cout<<a<<")"<<endl;
            }
            cout<<"("<<4<<", "<<4<<")"<<endl;
            exit(0);
        }
        int x3=pre[x2][y2].x,y3=pre[x2][y2].y;//没存完就递归存数(可以改循环)
        s.push(x3);
        s.push(y3);
        print(x3,y3);//递归
    
    }
    void gs() {//广搜(看名字就能看出来我才不用什么BFs当名字,花里胡哨的)
        while(q.empty() == 0) {
            int x = q.front();//这里可以用两个队列一个存x一个存y,但我喜欢这样
            q.pop();
            int y = q.front();
            q.pop();
            for(int i=1; i<=4; i++) {//神奇的搜索,自己悟
                int x2 = x + xx[i];//新节点的横坐标
                int y2 = y + yy[i];//纵坐标
                if(a[x2][y2] == 0 && x2 >= 0 && y2 >= 0 && x2 < 5 && y2 < 5) {//如果没搜过且不越界
                    q.push(x2);//存入
                    q.push(y2);
                    tot[x2][y2] = tot[x][y] + 1;//每一个节点都是由他的上一个节点扩展,所以是上一个+1;
                    a[x2][y2] = 1;//标记
                    if(pre[x2][y2].x == 0) {//如果是第一次搜
                        pre[x2][y2].x  = x;//记录
                        pre[x2][y2].y  = y;
                    }
                }
                if(x2 == 4 && y2 == 4) {//到达终点
                    print(4,4);//打印
                    return ;//结束
                }
            }
        }
    }
    int main() {
        for(int i=0; i<5; i++) {//输入
            for(int j=0; j<5; j++)
                cin>>a[i][j];
        }
        q.push(0);//以(0,0)为起点开始
        q.push(0);
        gs();//搜索
    
        return 0;
    }

    这其实也是一个广搜问题模板(自己写的,可能不正规不如其他好),其他广搜也可以用这个当模板

    ps:上面说的"神奇的东西"其实我也很难解释,大家想不明白可以画个图理解一下

  • 相关阅读:
    php正则表达式验证(邮件地址、Url地址、电话号码、邮政编码)
    laravel 事件广播
    windows apache 配置多个服务 站点 Apache Service Monitor
    apache配置多站点
    querySelector和querySelectorAll方法介绍
    document.domain与js跨域的问题
    用JS判断用户使用的是手机端还是pc端访问
    下载的firebug-lite压缩包的调用方法
    JS实现常用的分享到按钮
    转:不会定义jQuery插件,不要说会jQuery
  • 原文地址:https://www.cnblogs.com/lztzs/p/10736569.html
Copyright © 2011-2022 走看看