问答形式标记法

问答形式标记法

01迷宫

题目描述

有一个仅由数字 0011 组成的 n×nn \times n 格迷宫。若你位于一格 00 上,那么你可以移动到相邻 44 格中的某一格 11 上,同样若你位于一格 11 上,那么你可以移动到相邻 44 格中的某一格 00 上。

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

输入格式

第一行为两个正整数 n,mn,m

下面 nn 行,每行 nn 个字符,字符只可能是 00 或者 11,字符之间没有空格。

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

输出格式

mm 行,对于每个询问输出相应答案。

样例 #1

样例输入 #1

1
2
3
4
5
2 2
01
10
1 1
2 2

样例输出 #1

1
2
4
4

提示

对于样例,所有格子互相可达。

  • 对于 20%20\% 的数据,n10n \leq 10
  • 对于 40%40\% 的数据,n50n \leq 50
  • 对于 50%50\% 的数据,m5m \leq 5
  • 对于 60%60\% 的数据,n,m100n,m \leq 100
  • 对于 100%100\% 的数据,1n10001\le n \leq 10001m1000001\le m \leq 100000

思路是因为可以把迷宫想象成若干区块构成,相同区块之间可以互通,不同区块之间不能互通。

那么找到某一个区块,用bfs的手段就可以在二维数组map中找到所有可以与他相连可以互通的区块,于是就将这些区块的数量总和标在另一个数组visited中。

代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
#include<iostream>
#include<string.h>
#include<queue>
#define int long long
using namespace std;
int map[1005][1005]={0};
int visited[1005][1005]={0};
int dx[4]={1,0,-1,0};
int dy[4]={0,1,0,-1};

int sum;
int n,m;
typedef struct
{
int x;
int y;
}pos;
queue<pos>q;
queue<pos> save;
void cont(int x,int y)
{

sum=1;
pos temp;
temp.x=x;
temp.y=y;
visited[x][y]=-1;
q.push(temp);
while(!q.empty())
{

int tx=q.front().x;
int ty=q.front().y;

for(int i=0;i<4;i++)
{
if(tx+dx[i]>=0 && tx+dx[i]<n && ty+dy[i]>=0 && ty+dy[i]<n && visited[tx+dx[i]][ty+dy[i]]==0 &&map[tx+dx[i]][ty+dy[i]]==1-map[tx][ty])
{
visited[tx+dx[i]][ty+dy[i]]=-1;
sum++;
pos temp;
temp.x=tx+dx[i];
temp.y=ty+dy[i];
q.push(temp);
}
}
save.push(q.front());
//cout<<tx<<" "<<ty<<endl;
q.pop();
}
int tt=save.size();//把本次fs遍历过的点存到save中

for(int i=0;i<tt;i++)
{
visited[save.front().x][save.front().y]=sum;
save.pop();
}
}
signed main()
{
char t;
cin>>n>>m;
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
cin>>t;
map[i][j]=(long long)t-48;
}
}
int sx,sy;
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
if(visited[i][j]==0)
{
cont(i,j);
}
}
}
//for(int i=0;i<n;i++)
//{
// for(int j=0;j<n;j++)
// {
// cout<<visited[i][j]<<" ";
// }
// cout<<endl;
//}
for(int i=0;i<m;i++)
{
cin>>sx>>sy;
cout<<visited[sx-1][sy-1]<<endl;
}

return 0;
}