根据最高赞题解修改而来,按自己的理解写了注释
#include<bits/stdc++.h>
using namespace std;
char a[1005][1005];
int xa[4]={0,-1,0,1};//顺时针方向
int ya[4]={1,0,-1,0};
int ans[100002],f[1005][1005],n,m;//ans
void dfs(int i,int j,int ij,int v)
{
if(i<1||i>n||j<1||j>n||f[i][j]!=0||a[i][j]-'0'!=ij) return;//边界或无路
f[i][j]=v;//记录相应的坐标的第一次访问的次序,且标记该点--->点与点之间是可以相互联通的,联通的点之间,任意起点,移动格数相同
ans[v]++;//记录询问进入递归的次数,也就是移动的次数
for(int k=0;k<4;k++)
{
dfs(i+xa[k],j+ya[k],!ij,v);//四个方向遍历,!是取反 ,将0改为1,将1改为0
}
}
int main()
{
cin>>n>>m;
//输入
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
cin>>a[i][j];
// memset(f,-1,sizeof(f));//把f数组初始化为-1
for(int i=1;i<=m;i++) //m个起点
{
int x,y;
cin>>x>>y;
if(f[x][y]==0)
{
dfs(x,y,a[x][y]-'0',i);
}else
{
ans[i]=ans[f[x][y]]; //剪枝,已经访问过的下标直接从数组中取出答案
}
}
//输出结果
for(int i=1;i<=m;i++) cout<<ans[i]<<endl;
return 0;
}