【问题描述】
小明有一块空地,他将这块空地划分为 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:
#include <iostream>
#include <queue>
using namespace std;
const int N = 1100;
int n, m, k;
char a[N][N];
int dx[4] = {-1, 0, 1, 0};
int dy[4] = {0, 1, 0, -1};
struct node
{
int x, y, dist;
};
queue<node> q;
void bfs()
{
while(q.size())
{
node t = q.front(); // 取出队头
q.pop(); // 删除队头
if(t.dist == k) continue; // 满足了要求
for (int i = 0; i < 4; i ++) // 四个方向中,合法的入队
{
int x = t.x + dx[i], y = t.y + dy[i];
if(x < 0 || y < 0 || x >= n || y >= m || a[x][y] == 'g') continue;
a[x][y] = 'g'; // 长草
q.push({x, y, t.dist + 1}); // 新元素入队
}
}
}
int main()
{
cin >> n >> m;
for(int i = 0; i < n; i ++)
for(int j = 0; j < m; j ++)
{
cin >> a[i][j];
if(a[i][j] == 'g') q.push({i, j, 0}); // 所有'g'入队
}
cin >> k;
bfs();
for (int i = 0; i < n; i ++) puts(a[i]); // 字符串形式输出
return 0;
}