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;
}