2020蓝桥杯省赛校内模拟赛I题

2020蓝桥杯省赛校内模拟赛I题

问题描述
  小明有一块空地,他将这块空地划分为 n 行 m 列的小块,每行和每列的长度都为 1。
  小明选了其中的一些小块空地,种上了草,其他小块仍然保持是空地。
  这些草长得很快,每个月,草都会向外长出一些,如果一个小块种了草,则它将向自己的上、下、左、右四小块空地扩展,这四小块空地都将变为有草的小块。
  请告诉小明,k 个月后空地上哪些地方有草。
输入格式
  输入的第一行包含两个整数 n, m。
  接下来 n 行,每行包含 m 个字母,表示初始的空地状态,字母之间没有空格。如果为小数点,表示为空地,如果字母为 g,表示种了草。
  接下来包含一个整数 k。
输出格式
  输出 n 行,每行包含 m 个字母,表示 k 个月后空地的状态。如果为小数点,表示为空地,如果字母为 g,表示长了草。

样例输入
4 5
.g…
…
…g…
…
2
样例输出
gggg.
gggg.
ggggg
.ggg.

评测用例规模与约定
  对于 30% 的评测用例,2 <= n, m <= 20。
  对于 70% 的评测用例,2 <= n, m <= 100。
  对于所有评测用例,2 <= n, m <= 1000,1 <= k <= 1000。

这道题简单的bfs。
先开始我想的是。。每次跑一遍,然后跑k次。。这样出现了一个问题。bfs处理起来很麻烦。因为第k次的时候把下一次需要更新的也放到队列中了,还需要标记。比较麻烦

我们还不如把先开始有草坪的结点一个一个处理k次。分别单独处理。这样bfs就比较好跑啦~

代码部分:

#include <bits/stdc++.h>
using namespace std;
const int N = 1e3 + 10;

int n, m;
int k;
char a[N][N];
int dir[4][2] = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};
struct node
{
	int x;
	int y;
	int mon;
};
vector<node> grass;

int ch(int x, int y)
{
	return x >= 1 && x <= n && y >= 1 && y <= m;
}

int check(int mon, int x, int y)
{
	if (ch(x, y) && mon < k)
	{
		return 1;
	}
	return 0;
}

void bfs(node s)
{
	queue<node> q;
	q.push(s);
	
	while (!q.empty())
	{
		node t = q.front();
		q.pop();
		for (int i = 0; i < 4; i++)
		{
			int nowx = t.x + dir[i][0];
			int nowy = t.y + dir[i][1];
			if (check(t.mon, nowx, nowy))
			{
				a[nowx][nowy] = 'g';
				q.push({nowx, nowy, t.mon + 1});
			}
		}
	}
}

int main()
{
	cin >> n >> m;
	for (int i = 1; i <= n; i++)
	{
		for (int j = 1; j <= m; j++)
		{
			cin >> a[i][j];
			if (a[i][j] == 'g')
			{
				grass.push_back({i, j, 0});
			}
		}
	}
	cin >> k;
	for (int i = 0; i < grass.size(); i++)
	{
		bfs(grass[i]);
	}
	for (int i = 1; i <= n; i++)
	{
		for (int j = 1; j <= m; j++)
		{
			cout << a[i][j];
		}
		cout << endl;
	}
	return 0;
} 
发布了112 篇原创文章 · 获赞 3 · 访问量 2627

猜你喜欢

转载自blog.csdn.net/qq_44624316/article/details/105007487