• (考试大整理~)迷宫


    (maze.cpp/c/pas)

    Description

    Karles 和朋友到迷宫玩耍,没想到遇上了 10000000 年一次的大洪水,好在 Karles 是一个喜欢思考的人,他发现迷宫的地形和洪水有如下性质:

    ①迷宫可以被看做是一个 N*M 的矩形方阵,其中左上角坐标为(1,1),右下角坐标为(n,m),每个格子(i,j)都有一个高度 h(i,j)。

    ②洪水从(sx,sy)开始,如果一个格子被洪水淹没,那这个格子四周比它低(或相同)的格子也会被淹没。

    现在 Karles 想请你帮忙算算,有多少个格子不会被淹没,以及 Karles 想问一下格子(x,y)是否被淹没,如果被淹没的话就输出”Yes”,否则输出”No”。

    Input

    第一行包含两个整数 n,m。

    以下 n 行,每行 m 个数,第 i 行第 j 个数表示格子高度 h(i,j)。

    下面一行包含两个整数 sx,sy,表示最初被洪水淹没的格子。

    下面一行包含一个整数 q,表示询问的数量。

    最后 q 行每行包含两个整数 x,y,表示询问的格子。

    Output

    输出的第一行,为永远不会被淹没的格子的数量。

    以下 q 行,为格子被淹没的情况,输出”Yes”或者”No”(不包含引号)

    Example

    maze.in 

    3 3

    1 2 3

    2 3 4

    3 4 5

    2 2

    2

    1 2

    2 3

    maze.out

    5

    Yes

    No

    Hint

    对于 10%的数据,(sx,sy)为迷宫内的最高点。

    对于 30%的数据,1<=N,M<=5,q=1。

    对于 60%的数据,1<=N,M<=100,q<=100。

    对于 100%的数据,1<=N,M<=2000,q<=1000。

    解题思路:

      因为题目的意思为从一个起点开始,

      向它的四周扩展,所以开2个数组,

      为移动方向,如果找到比它低的,计数器就++;

      最终输出总的m*n-计数器的数;

    上代码:

    #include<cstdio>
    #include<queue>
    using namespace std;
    
    const int M = 2001;
    int n,m,tot=1,T,x,y;
    int dx[5] = {0,1,-1,0,0}; //搜索的方向
    int dy[5] = {0,0,0,1,-1};
    bool vis[M][M];//记录是否能够被淹没,初始化均为0
    int g[M][M],x1,y1;
    struct data {
        int x,y;
    };
    queue<data>q;
    
    void bfs() {
        data u,v;
        vis[x1][y1]=true;
        u.x=x1,u.y=y1;
        q.push(u);
        while(!q.empty()) {
            u=q.front(); q.pop();
            x=u.x,y=u.y;
            for(int i=1; i<=4; i++) { //扩展的四个方向
                int xx=x+dx[i],yy=y+dy[i];
                if(yy>=1&&xx>=1&&yy<=m&&xx<=n&&g[xx][yy]<=g[x][y]&&!vis[xx][yy]) {
                    vis[xx][yy]=true;//进行标记
                    tot++;
                    v.x=xx,v.y=yy;
                    q.push(v);
                }
            }
        }
    }
    
    int main() {
        freopen("maze.in","r",stdin);
        freopen("maze.out","w",stdout);
        scanf("%d %d",&n,&m);
        for(int i=1; i<=n; i++)
            for(int j=1; j<=m; j++)
                scanf("%d",&g[i][j]);
        scanf("%d %d",&x1,&y1);
        bfs();
        printf("%d
    ",n*m-tot);//总共的减去被淹没的
        scanf("%d",&T);
        while(T--) {
            scanf("%d %d",&x,&y);
            if(vis[x][y]) printf("Yes
    ");
            else printf("No
    ");
        }
        fclose(stdin);fclose(stdout);
        return 0;
    }

    如果运气好也是错,那我倒愿意错上加错!

    ❀❀❀❀❀❀❀❀❀❀❀❀❀❀❀❀❀❀❀❀❀

  • 相关阅读:
    .NET WinForm下StatusStrip控件如何设置分隔线及部分子控件右对齐
    winform 弹出窗体指定位置
    命名空间“System.Web”中不存在类型或命名空间名称“Optimization”(是否缺少程序集引用?)
    SQL之case when then用法详解
    VS2015编译错误:调用的目标发生了异常--->此实现不是Windows平台FLPS验证的加密算法的一部分。
    .NET Core 控制台中文乱码问题!
    IOC 依赖注入 Unity
    《重构:改善代码的既有设计》读书笔记
    .NET中的堆(Heap)和栈(Stack)的本质
    浅谈 Sql Server 游标
  • 原文地址:https://www.cnblogs.com/zxqxwnngztxx/p/6679712.html
Copyright © 2020-2023  润新知