输入
2 2
01
10
1 1
2 2
输出
4
4
既然一个位置能到达另一个位置,那么反过来一样能达到,因此,可以把一个位置能到达的所有位置看成是一个连通块,在一个连通块内,任何位置所到达的格子一样,这样一来,把连通块的位置都进行标记,再搜索没标记的,再看成一个连通块,直至所有位置搜索完。
关键就在vis上面,每次不用清零,直接判断有没有访问过,访问过就不用在访问了。
#include<iostream>
#include<stdio.h>
#include<iomanip>
#include<stack>
#include<queue>
#include<cstdlib>
#include <algorithm>
#include<string.h>
#include<math.h>
#define llu unsigned long long
using namespace std;
int n,m;
char a[1010][1010];//注意这里用的char
int vis[1010][1010]={
0};
int ans[1010*1010]={
0};
int dir[4][2]={
0,1,0,-1,1,0,-1,0};
struct node{
int x;
int y;
}start,now;
int num=0;
int bfs(int x,int y)
{
int sum=1;
queue<node> q;
num++;
start.x=x;
start.y=y;
q.push(start);
vis[x][y]=num;
while(!q.empty())
{
now=q.front();
q.pop();
for(int i=0;i<4;i++)
{
start.x=now.x+dir[i][0];
start.y=now.y+dir[i][1];
if(start.x>=1&&start.y>=1&&start.x<=n&&start.y<=n&&vis[start.x][start.y]==0)
{
if(a[now.x][now.y]=='0'&&a[start.x][start.y]=='1'||a[now.x][now.y]=='1'&&a[start.x][start.y]=='0')
{
vis[start.x][start.y]=num;
q.push(start);
sum++;
}
}
}
}
ans[num]=sum;
return sum;
}
int main()
{
int x,y;
cin>>n>>m;
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
cin >> a[i][j];
}
}
while(m--){
cin >> x >> y;
if(vis[x][y]!=0)
cout<<ans[vis[x][y]]<<endl;
else{
int sum=bfs(x,y);
cout << sum << endl;
}
}
return 0;
}