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\n", a[maze[i][j]]);
78     }
79     scanf("%d%d", &i, &j);
80     printf("%d", a[maze[i][j]]);
81     return 0;
82 }

 

转载于:https://www.cnblogs.com/yBaka/p/7401048.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值