将方向用自定义数组循环化 ,读入时注意字符串处理,走过的地方记忆化。并查集,不同联通块采用不同颜色标记记忆,方便多次查询。并记忆每种颜色染色数量(即联通块大小)。
#include<cstdio>
#include<cmath>
#include<cstring>
#include<ctime>
#include<iostream>
#include<algorithm>
using namespace std;
const int N=1005;
char map[N][N];
int n,m,tot;
int ans[N*N],f[N][N];
int X[4]={0,0,-1,1};
int Y[4]={-1,1,0,0};
bool ask(int x,int y){
if(!x||!y||x>n||y>n||f[x][y]) return 0;
return 1;
}
void Dfs(int x,int y){
f[x][y]=tot;
ans[tot]++;
for(int i=0;i<4;i++){
int l=x+X[i];
int r=y+Y[i];
if(map[x][y]!=map[l][r]&&ask(l,r))
Dfs(l,r);
}
}
int main(){
freopen("p1141.in","r",stdin);
// freopen("p1141.out","w",stdout);
scanf("%d %d\n",&n,&m);
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
scanf("%c",&map[i][j]);
}
scanf("\n");
}
for(int i=1;i<=m;i++){
int x,y;
scanf("%d %d\n",&x,&y);
if(!f[x][y]) {
tot++;
Dfs(x,y);
}
printf("%d\n",ans[f[x][y]]);
}
fclose(stdin);
// fclose(stdout);
return 0;
}