https://www.luogu.com.cn/problem/P1141

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

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

输入格式
第1行为两个正整数n,。

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

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

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

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

通过设置 vis 为不同的值,避免重复初试化 vis 。
如果从某点可以到达一个区域,那么从该区域中的任何一点都可以到达相同的区域。

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
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define sf(n) scanf("%d",&n)
#define pf(n) printf("%d",n)
#define pfc(c) printf(c)
#define fi(i,s,t) for(int i=s;i<t;i++)
#define fd(s,t) for(int i=s-1;i>=t;i--)
#define mem(a,c) memset(a,c,sizeof(a))
const int INF=0x3f3f3f3f;
const int MAX=1000+10;
int n,m,x,y,vis[MAX][MAX],rec[100005];
char a[MAX][MAX];
int aw[4][2]={-1,0,0,1,1,0,0,-1},ans;
bool judge(int x,int y){
if(x<1 || x>n || y<1 || y>n ) return false;
return true;
}
struct node{
int x,y;
node(int _x,int _y){
x=_x;y=_y;
}
};
queue <node> q;
int bfs(node t,int tag){
if(rec[vis[t.x][t.y]]!= 0)
return rec[vis[t.x][t.y]];
q.push(t);
vis[t.x][t.y]=tag;
ans =0;
while(!q.empty()){
node c = q.front();
q.pop();
ans ++;
fi(i,0,4){
int tx= c.x + aw[i][0],ty= c.y + aw[i][1];
if(judge(tx,ty) && vis[tx][ty]<tag && a[tx][ty]!=a[c.x][c.y]){
q.push(node(tx,ty));
vis[tx][ty]=tag;
}
}
}
return rec[vis[t.x][t.y]]=ans;
}
int main(){
freopen("in","r",stdin);
sf(n);sf(m);
fi(i,1,n+1)
scanf("%s",a[i]+1);
fi(i,1,m+1){
sf(x);sf(y);
pf(bfs(node(x,y),i));pfc("\n");
}
return 0;
}