写法可能有点怪,思路就是在查找的过程中将联通的快赋一样的值。
#include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>
#define x first
#define y second
using namespace std;
typedef pair<int,int>PII;
const int N=1005;
int n,m,res[N][N];
char s[N][N];//输入
bool st[N][N],str[N][N];
int dx[4]={0,0,1,-1},dy[4]={1,-1,0,0};//偏移量
void bfs(PII start){
int sum=1;
memset(st,false,sizeof s);
st[start.x][start.y]=true;
queue<PII>q;
q.push(start);
while(q.size()){
PII t=q.front();
q.pop();
for(int i=0;i<4;i++){
int x=t.x+dx[i],y=t.y+dy[i];
if(x<0||x>=n||y<0||y>=n)continue;
if(st[x][y])continue;
if(s[t.x][t.y]==s[x][y])continue;
sum++;
st[x][y]=true;
q.push({x,y});
}
}
res[start.x][start.y]=sum;
str[start.x][start.y]=true;//赋值过的标记
//后面将与点start联通的点赋予相同的值
q.push(start);
while(q.size()){
PII t=q.front();
q.pop();
for(int i=0;i<4;i++){
int x=t.x+dx[i],y=t.y+dy[i];
if(x<0||x>=n||y<0||y>=n)continue;//越界
if(str[x][y])continue;//赋值过
if(s[t.x][t.y]==s[x][y])continue;//不连通
str[x][y]=true;//赋值过的标记
res[x][y]=sum;
q.push({x,y});
}
}
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=0;i<n;i++)scanf("%s",s[i]);
PII start;
int a,b;
while(m--){
scanf("%d%d",&a,&b);
if(!str[a-1][b-1]){//如果没有查过则进行广搜
start={a-1,b-1};
bfs(start);
printf("%d\n",res[a-1][b-1]);
}else printf("%d\n",res[a-1][b-1]);//查过了直接输出
}
return 0;
}