• 这些搜索套路好深。。。


    话不多说,练习搜索

    其中两个题比较典型,拿出来讲讲

    1.迷宫

    题意较简单,n*m迷宫中,从(x,y)到(a,b)有几条路

    代码奉上(这题是广搜?用的深搜):

    #include<bits/stdc++.h> //这题用队列MLE,换种思路TLE,然后用了深搜
    using namespace std;
    int n,m,t,sx,sy,fx,fy;
    bool ok[6][6];
    int mx[4]={0,-1,0,1};
    int my[4]={-1,0,1,0};
    bool vis[6][6]; //储存该点在此次访问路径是否被访问过
    int sum;
    inline bool inside(int x,int y){    //判断是否在界内,不然没有意义
        return (1<=x&&x<=n&&1<=y&&y<=m);
    }
    void search(int x,int y){
        if(x==fx&&y==fy){      //到达终点情况
            sum++;
            return;//(void可以return后不加东西)
        }
        for(int i=0;i<=3;i++){
            if((inside(x+mx[i],y+my[i]))&&(ok[x+mx[i]][y+my[i]])&&(!vis[x+mx[i]][y+my[i]])){
                vis[x+mx[i]][y+my[i]]=1;
                search(x+mx[i],y+my[i]);
                vis[x+mx[i]][y+my[i]]=0; //返回状态
            }
        }
    }
    int main(){
        scanf("%d%d%d%d%d%d%d",&n,&m,&t,&sx,&sy,&fx,&fy);
        for(int i=1;i<=n;i++){
            for(int j=1;j<=m;j++) ok[i][j]=1;
        }
        for(int i=1;i<=t;i++){
            int zx,zy;
            scanf("%d%d",&zx,&zy);
            ok[zx][zy]=0;
        }
        vis[sx][sy]=1; //标记起点,一开始没加wa了5个点
        search(sx,sy);
        cout<<sum;
        return 0;
    }

    这题深搜易敲,思路简单

    2._GC滑迷宫(跟某龚姓网友没有半点关系!(眨眼眨眼))

    以下复制:

    题目背景

    _GC买了一双蔡徐坤一代。(重点,记笔记!) 

    题目描述

    _GC进入了一个n*m的迷宫。
    本题的特殊之处在于,_GC只能滑着走。具体来说就是,选定一个方向后,_GC会一直向该方向滑,直到撞到墙。
    会给出_GC的起始位置。只需要滑出去即可。
    求最小的撞墙次数。

    这题求“最小次数”,要用广搜,先要精通队列

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    int n,m,sx,sy,a[25][25];
    bool vis[25][25];
    int mx[4]={0,1,0,-1};
    int my[4]={1,0,-1,0};
    struct pos{
        int x,y,sum;
        pos(int a,int b,int c):x(a),y(b),sum(c){}; //构造函数,在这里就是赋值
    };
    queue<pos> q; //队列
    inline bool inside(int x,int y){      //判断界外
        return (1<=x&&x<=n)&&(1<=y&&y<=m);
    }
    int main(){
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++){
            for(int j=1;j<=m;j++) scanf("%d",&a[i][j]);
        }
        scanf("%d%d",&sx,&sy);
        if(a[sx][sy]){        //出生卡墙则无解(谁出的数据?)
            cout<<-1;
            return 0;
        }
        if(sx==1||sx==n||sy==1||sy==m){ //出生在边界则0步
            cout<<0;
            return 0;
        }
        q.push(pos(sx,sy,0)); //队列常用函数,压入
        while(!q.empty()){
            pos h=q.front();  //取队首元素
            q.pop();          //弹出刚取的元素
            if(h.x==1||h.x==n||h.y==1||h.y==m){ //到达则输出
                cout<<h.sum-1;
                return 0;
            }
            for(int i=0;i<=3;i++){
                int nowx=h.x;
                int nowy=h.y;
                while((!a[nowx+mx[i]][nowy+my[i]])&&(inside(nowx+mx[i],nowy+my[i]))){
                    nowx+=mx[i];  //此循环里是控制滑动
                    nowy+=my[i];
                }
                if(!vis[nowx][nowy]){
                    vis[nowx][nowy]=1; //同上面一题,保存是否走过
                    q.push(pos(nowx,nowy,h.sum+1));
                }
            }
        }
        cout<<-1; //如果以上均无路径,则无解,输出-1
        return 0;
    }

    分别是深搜和广搜,个人喜欢深搜,毕竟代码短。。。

  • 相关阅读:
    eclipse中解决git分支合并冲突
    git 放弃本地修改,强制拉取更新
    廖雪峰Git入门教程
    如何实现Proxifier只代理部分程序
    Proxifier代理工具简介和下载
    Navicat Premium 12.0.18安装与激活
    Teamviewer远程控制
    夜神安卓模拟器下载及简介
    Fiddler2如何对Android应用进行抓包
    谷歌浏览器添加JSON-handle插件
  • 原文地址:https://www.cnblogs.com/648-233/p/10712672.html
Copyright © 2020-2023  润新知