CF EDU 118 E - Crazy Robot
E - Crazy Robot
搜索
- 搜索能变成 + 的点,第一次搜到的时候入队
- 枚举队头的点的邻居,判断是否能变成 + ,能的话也入队(判断的方法就是如果周围的 '.' 的个数 <= 1 就可以变成 + )
关键:只让能变成 + 的入队,并且每个 + 的邻居都要判断是否能变成 + ,不能因为某个邻居被判断过了就跳过,因为这个邻居的邻居中可能有的点从 '.' -> '+'
#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
#include <cmath>
#include <queue>
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
int n, m;
int sx, sy;
int dx[] = {1, 0, -1, 0};
int dy[] = {0, 1, 0, -1};
int main()
{
int T;
scanf("%d", &T);
while(T--)
{
scanf("%d%d", &n, &m);
vector<vector<char> > s(n + 10, vector<char>(m + 10));
vector<vector<bool> > vis(n + 10, vector<bool>(m + 10));
for (int i = 1; i <= n; i++)
{
getchar();
for (int j = 1; j <= m; j++)
{
scanf("%c", &s[i][j]);
if (s[i][j] == 'L')
sx = i, sy = j;
}
}
s[sx][sy] = '+';
auto check = [&](int x, int y)
{
return s[x][y] == '.';
};
queue<PII> q;
q.push({sx, sy});
while(!q.empty())
{
auto [x, y] = q.front();
q.pop();
if (vis[x][y])
continue;
//每次都要把队头元素的四个方向都判断一下是否能产生新的+,不能因一个邻居被判断过就不判了
for (int i = 0; i < 4; i++)
{
int tx = x + dx[i], ty = y + dy[i];
if (tx < 1 || tx > n || ty < 1 || ty > m || s[tx][ty] != '.')
continue;
if (check(tx+1, ty) + check(tx-1, ty) + check(tx, ty+1) + check(tx, ty-1) < 2)
{
s[tx][ty] = '+';
// 只有+才能入队
q.push({tx, ty});
}
}
}
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= m; j++)
{
if (i == sx && j == sy)
printf("L");
else
printf("%c", s[i][j]);
}
puts("");
}
}
return 0;
}