这些搜索套路好深。。。

话不多说,练习搜索

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

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;
}

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

posted @ 2019-04-15 19:54  _Alex_Mercer  阅读(280)  评论(0编辑  收藏  举报