• 01迷宫(记忆化搜索)


    01迷宫

    题目描述:
    有一个由01组成的n*n格迷宫,若你位于一格0上,那么你可以移动到相邻4格中的某一格1上,同样若你位于一格1上,那么你可以移动到相邻4格中的某一格0上。那么对于给定的迷宫,询问从某一格开始能移动到多少格。
    输入描述:
    输入的第1行为两个正整数n,m。
    下面n行,每行n个字符,字符只可能是0或者1,字符之间没有空格。
    接下来m行,每行2个用空格分隔的正整数i,j,对应了迷宫中第i行第j列的一个0,询问从这一格开始能移动到多少格。
    输出描述:
    输出包括m行,对于每个询问输出答案。
    样例输入:
    2 2
    01
    10
    1 1
    2 2
    样例输出:
    4
    4
    数据范围及提示:
    样例说明:
    所有格子互相可达。
    数据规模:
    对于20%的数据,n≤10;
    对于40%的数据,n≤50;
    对于50%的数据,m≤5;
    对于60%的数据,n≤100,m≤100;
    对于100%的数据,n≤1000,m≤1000000。
    思路:
    因为有多个查询,为了减少不必要的搜索,使用记忆化搜索

    #include<iostream>
    #include<cstdio>
    #include<queue>
    using namespace std;
    const int maxn=1010;
    int n,m,map[maxn][maxn],me[maxn][maxn];
    int xx[5]={0,1,-1,0,0},
        yy[5]={0,0,0,1,-1};
    char s[maxn];
    struct node
    {
        int x;
        int y;
    }a;
    struct tong
    {
        int x;
        int y;
    }b[maxn*maxn];
    bool flag[maxn][maxn];
    queue<node> q;
    void search(node a)
    {
        if(me[a.x][a.y])
        {
            printf("%d
    ",me[a.x][a.y]);
            return;
        }
        int cnt=0;
        q.push(a);
        while(!q.empty())
        {
            a=q.front();
            q.pop();
            for(int i=1;i<=4;i++)
            {
                node t;
                t.x=a.x+xx[i];
                t.y=a.y+yy[i];
                if(t.x>=1&&t.x<=n&&t.y>=1&&t.y<=n&&!flag[t.x][t.y]&&map[a.x][a.y]+map[t.x][t.y]==1)
                {
                    flag[t.x][t.y]=1;
                    cnt++;
                    b[cnt].x=t.x;
                    b[cnt].y=t.y;
                    q.push(t);
                }
            }
        }
        for(int i=1;i<=cnt;i++)
        me[b[i].x][b[i].y]=cnt;
        if(cnt==0) cnt++;
        printf("%d
    ",cnt);
    }
    int main()
    {
        cin>>n>>m;
        for(int i=1;i<=n;i++)
        {
            cin>>s;
            for(int j=0;j<n;j++)
            map[i][j+1]=s[j]-'0';
        }
        for(int i=1;i<=m;i++)
        {
            scanf("%d%d",&a.x,&a.y);
            search(a);
        }
        return 0;
    }
  • 相关阅读:
    rust中的arm交叉编译
    Dockerfile简单编写
    docker常用命令
    linux下tf/u盘格式化
    rust查看支持的架构列表
    linux内核版本修改
    cgo引用外部c文件注意1
    redis服务允许外部ip访问开启
    redis密码修改
    setInterval和setTimeout的使用区别
  • 原文地址:https://www.cnblogs.com/cax1165/p/6070926.html
Copyright © 2020-2023  润新知