zoukankan      html  css  js  c++  java
  • ACM搜索专题(BFS,DFS,记忆化搜索等)

    本次的搜索专题的题目来源主要有 洛谷vjudege 上的搜索专题

    一.BFS

    1. 01迷宫

    题目链接:https://www.luogu.org/problemnew/show/P1141
    题目分析:这个题算是一个入门级的BFS搜索,题目中所需要的输出就是从一个格子可以最多走多少个格子,格子不能重复。
    这个题使用BFS,DFS都可以,我先来讲一下BFS的做法
    这个题就是一个带方向的搜索,为了方便搜索,我们设置两个数组分别存储方向。

    因为每一个点都有x,y两个坐标,所以这里我使用一个结构体保存每一个点

    struct node
    {
        int x,y;
    };
    

    可以看到这个题的m的取值还是很大的,如果不保留状态,每一次都重新搜索肯定会超时,所以这里我使用一个数组保存计算过的点的格数,采用记忆化搜索

    int b[1000005][2];        //记录搜索过的点
    int f[1001][1001];         //存储每个点对应的答案
    

    接下来是完整的代码

    #include<bits/stdc++.h>
    using namespace std;
    char Map[1001][1001];       //存放整个图,为了节省空间这里使用字符型
    int vis[1001][1001];       //记录点的状态
    int b[1000005][2];        //记录搜索过的点
    int f[1001][1001];         //存储每个点对应的答案
    int v_x[4]={1,-1,0,0};
    int v_y[4]={0,0,1,-1};
    int num;
    int n,m;
    struct node
    {
        int x,y;
    };
    void bfs(int x,int y)
    {
        queue<node>qu;
        node a1,a2;
        a1.x=x;a1.y=y;
        num++;
        b[num][0]=x;
        b[num][1]=y;
        vis[x][y]=1;
        qu.push(a1);
        while (!qu.empty()) {
            node a=qu.front();
            qu.pop();
            for (int i=0; i<4; i++) {
                int nx=a.x+v_x[i],ny=a.y+v_y[i];
                a2.x=nx;a2.y=ny;
                if (vis[nx][ny]==0&&Map[a.x][a.y]!=Map[nx][ny]&&nx>0&&nx<=n&&ny>0&&ny<=n) {
                    num++;
                    vis[nx][ny]=1;
                    b[num][0]=nx;
                    b[num][1]=ny;
                    qu.push(a2);
                }
            }
        }
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        for (int i=1; i<=n; i++) {
            scanf("%s",Map[i]+1);
        }
        for (int i=1; i<=n; i++) {
            for (int j=1; j<=n; j++) {
                if (vis[i][j]==0) {
                    bfs(i,j);
                    for (int i=1; i<=num; i++) {
                        f[b[i][0]][b[i][1]]=num;
                    }
                    num=0;
                }
            }
        }
        while (m--) {
            int x,y;
            scanf("%d%d",&x,&y);
            printf("%d
    ",f[x][y]);
        }
        
    }
    
    

    这个题里我使用了c++的队列,在C中需要自己写,这也是在做算法竞赛的时候使用c++快捷的一个理由吧,需要了解更多的同学可以去看下c++的STL标准库。
    因为我使用了一个数组存储遍历过的点的格数,所以我只需要遍历一遍,然后不断的输入m,输出对应的值即可,也就是这段代码

      for (int i=1; i<=n; i++) {
            for (int j=1; j<=n; j++) {
                if (vis[i][j]==0) {
                    bfs(i,j);
                    for (int i=1; i<=num; i++) {
                        f[b[i][0]][b[i][1]]=num;
                    }
                    num=0;
                }
            }
        }
        while (m--) {
            int x,y;
            scanf("%d%d",&x,&y);
            printf("%d
    ",f[x][y]);
        }
    

    接下来是使用DFS的做法,代码会简洁很多

    char Map[1001][1001];
    int b[1000005][2];
    int f[1001][1001];
    int vis[1001][1001];
    int v_x[4]={1,-1,0,0};
    int v_y[4]={0,0,1,-1};
    int n,m;
    int num;
    void dfs(int x,int y)
    {
        num++;
        vis[x][y]=1;
        b[num][0]=x;
        b[num][1]=y;
        for (int i=0; i<4; i++) {
            int fx=x+v_x[i];
            int fy=y+v_y[i];
            if (fx>0&&fx<=n&&Map[fx][fy]!=Map[x][y]&&!vis[fx][fy]&&fy>0&&fy<=n) {
                dfs(fx, fy);
            }
        }
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        for (int i=1; i<=n; i++) {
            scanf("%s",Map[i]+1);
        }
        for (int i=1; i<=n; i++) {
            for (int j=1; j<=n; j++) {
                if (!vis[i][j]) {
                    dfs(i, j);
                    for (int t=1; t<=num; t++) {
                        f[b[t][0]][b[t][1]]=num;
                    }
                    num=0;
                }
            }
        }
        while (m--) {
            int a,b;
            scanf("%d%d",&a,&b);
            printf("%d
    ",f[a][b]);
        }
    }
    
    
  • 相关阅读:
    C#面向对象
    C#语句
    C#语言数据类型
    Jupyter Notebook(iPython)
    BeautifulSoup模块
    requests模块
    爬虫基本原理
    版本控制系统
    支付宝支付
    django内置组件——ContentTypes
  • 原文地址:https://www.cnblogs.com/cnsec/p/11830676.html
Copyright © 2011-2022 走看看