思路:只有两个连通块,先标记一个连通块。之后将这个连通块全部放入队列跑一个bfs即可。
#include <bits/stdc++.h>
using namespace std;
const int N = 121;
int fx[] = {0, 0, 1, -1};
int fy[] = {1, -1, 0, 0};
bool vis[N][N];
string ph[N];
struct no {
int x,y,cnt;
};
int main()
{
int n,m; cin>>n>>m;
for(int i = 0; i < n; ++i) cin>>ph[i];
bool ok = false;
for(int i = 0; i < n; ++i) {
for(int j = 0; j < m; ++j) {
if(ph[i][j] == 'X') {
auto dfs = [&](auto &&self, int x, int y) -> void {
vis[x][y] = 1;
for(int i = 0; i < 4; ++i) {
int xx = x + fx[i], yy = y + fy[i];
if(xx < 0 || xx >= n || yy < 0 || yy >= m) continue;
if(ph[xx][yy] == '.' || vis[xx][yy]) continue;
self(self, xx ,yy);
}
};
dfs(dfs,i,j);
ok = true;
break;
}
}
if(ok) break;
}
queue<no> q;
for(int i = 0; i < n; ++i) {
for(int j = 0; j < m; ++j) {
if(vis[i][j]) q.push({i, j, 0});
}
}
while(q.size()) {
auto tmp = q.front(); q.pop();
for(int i = 0; i < 4; ++i) {
int xx = tmp.x + fx[i], yy = tmp.y + fy[i];
if(xx < 0 || xx >= n || yy < 0 || yy >= m) continue;
if(vis[xx][yy]) continue;
vis[xx][yy] = 1;
if(ph[xx][yy] == 'X') {
cout<<tmp.cnt<<endl;
return 0;
}
q.push({xx, yy, tmp.cnt + 1});
}
}
}