CF EDU 118 E - Crazy Robot

E - Crazy Robot

搜索

  1. 搜索能变成 + 的点,第一次搜到的时候入队
  2. 枚举队头的点的邻居,判断是否能变成 + ,能的话也入队(判断的方法就是如果周围的 '.' 的个数 <= 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;
}

posted @ 2022-05-12 19:58  hzy0227  阅读(15)  评论(0编辑  收藏  举报