主要是思路:这题思路应该特别好想来着
就是看询问的时候,如果这个点已经处于之前被搜索过的 连通块 内,直接输出存储的答案
否则进行一次 bfs,然后更新存储答案的 res 数组
代码如下
#include <iostream>
#include <cstring>
#include <vector>
#include <queue>
using namespace std;
typedef pair<int, int> pii;
const int N = 1010;
char g[N][N], res[N][N], st[N][N];
pii q[N * N];
int n, m;
void bfs(int x, int y)
{
int dx[4] = {-1, 1, 0, 0}, dy[4] = {0, 0, -1, 1};
vector<pii> blocks;# 存储这次搜索中所有遇到的新元素
q[0] = {x, y};
blocks.push_back({x, y});
st[x][y] = true;
int hh = 0, tt = 0;
while(hh <= tt)
{
auto t = q[hh ++];
for(int i = 0; i < 4; i ++)
{
int ax = t.first + dx[i], ay = t.second + dy[i];
if(ax < 0 || ax >= n || ay < 0 || ay >= n) continue;
if(st[ax][ay]) continue;
if(g[ax][ay] == g[t.first][t.second]) continue;
st[ax][ay] = true;
blocks.push_back({ax, ay});
q[++ tt] = {ax, ay};
}
}
# bfs结束后更新一下res数组
int cnt = blocks.size();
while(!blocks.empty())
{
auto t = blocks.back();
blocks.pop_back();
res[t.first][t.second] = cnt;
}
}
int main()
{
cin >> n >> m;
for(int i = 0; i < n; i ++)
scanf("%s", &g[i]);
while(m --)
{
int x, y;
scanf("%d%d", &x, &y);
x -- , y --;
if(!res[x][y]) bfs(x, y);
printf("%d\n", res[x][y]);
}
return 0;
}