• Luogu P1141 01迷宫(bfs)


     P1141 01迷宫

    题目描述

    有一个仅由数字0与1组成的n×n格迷宫。若你位于一格0上,那么你可以移动到相邻4格中的某一格1上,同样若你位于一格1上,那么你可以移动到相邻4格中的某一格0上。

    你的任务是:对于给定的迷宫,询问从某一格开始能移动到多少个格子(包含自身)。

    输入输出格式

    输入格式:

    输入的第1行为两个正整数n,m。

    下面n行,每行n个字符,字符只可能是0或者1,字符之间没有空格。

    接下来m行,每行2个用空格分隔的正整数i,j,对应了迷宫中第i行第j列的一个格子,询问从这一格开始能移动到多少格。

    输出格式:

    输出包括m行,对于每个询问输出相应答案。

    输入输出样例

    输入样例#1:
    2 2
    01
    10
    1 1
    2 2
    
    输出样例#1:
    4
    4
    

    说明

    所有格子互相可达。

    对于20%的数据,n≤10;

    对于40%的数据,n≤50;

    对于50%的数据,m≤5;

    对于60%的数据,n≤100,m≤100;

    对于100%的数据,n≤1000,m≤100000。

      这道题有很多方法我这里讲一下bfs的一种。

      这道题是一个连通块的问题,什么是连通块?百度连通图。

      只要求出每个连通分量,那么再询问即可。

     1 #include <cstdio>
     2 #include <queue>
     3 using namespace std;
     4 
     5 
     6 int m, n;
     7 char map[1005][1005];
     8 //标记变量 标记属于哪个连通块
     9 int maze[1005][1005];
    10 //第几个连通块里最大有多少块
    11 int a[1000005];
    12 //四种移动方式
    13 int mx[5] = {233, -1, 1, 0, 0};
    14 int my[5] = {233, 0, 0, -1, 1};
    15 
    16 struct point
    17 {
    18     int x, y;
    19 };
    20 queue<point> q;
    21 
    22 
    23 
    24 int main()
    25 {
    26     scanf("%d%d", &n, &m);
    27     for(int k=1; k<=n; k++)
    28     {
    29         scanf("%s", &map[k][1]);
    30     }
    31     
    32     //预处理
    33     int r = 0, nx, ny, t;
    34     for(int i=1; i<=n; i++)
    35     {
    36         for(int j=1; j<=n; j++)
    37         {
    38             //如果map[i][j]不属于已求出的连通块
    39             if(!maze[i][j])
    40             {
    41                 point p1;
    42                 p1.x = i;
    43                 p1.y = j;
    44                 q.push(p1);
    45                 r++;    //r表示是第几连通块
    46                 a[r]++;    //第r个连通块的块数++
    47                 maze[i][j] = r;
    48                 while(!q.empty())
    49                 {
    50                     point p2 = q.front();
    51                     q.pop();
    52                     for(int k=1; k<=4; k++)
    53                     {
    54                         nx = p2.x + mx[k];
    55                         ny = p2.y + my[k];
    56                         //判断出界 与 跑到其他连通块 与 01
    57                         if(nx>=1 && nx<=n && ny>=1 && ny<=n && !maze[nx][ny] && (map[p2.x][p2.y] != map[nx][ny]))
    58                         {
    59                             maze[nx][ny] = r;    //标记连通块
    60                             a[r]++;                //块数++
    61                             point p3;
    62                             p3.x = nx;
    63                             p3.y = ny;
    64                             q.push(p3);
    65                         }
    66                     }
    67                 }
    68             }
    69         }
    70     }
    71     
    72     //询问
    73     int i, j;
    74     for(int k=1; k<m; k++)
    75     {
    76         scanf("%d%d", &i, &j);
    77         printf("%d
    ", a[maze[i][j]]);
    78     }
    79     scanf("%d%d", &i, &j);
    80     printf("%d", a[maze[i][j]]);
    81     return 0;
    82 }
  • 相关阅读:
    Docker磁盘垃圾清理
    什么是容器编排?
    Docker 容器连接
    docker入门操作整理
    Docker学习的几个建议和技巧
    支付清结算之电商侧处理
    在Linux 中进入单用户模式的技巧
    教你如何构建异步服务器和客户端的 Kotlin 框架 Ktor
    NetSuite助力各行业企业快速发展
    linux需要你的不懈努力
  • 原文地址:https://www.cnblogs.com/yBaka/p/7401048.html
Copyright © 2020-2023  润新知