一、原文
题目链接:https://www.luogu.com.cn/problem/P2960。(洛谷)
Farmer John一直努力让他的草地充满鲜美多汁的而又健康的牧草。可惜天不从人愿,他在植物大战人类中败下阵来。邪恶的乳草已经在他的农场的西北部份占领了一片立足之地。
草地像往常一样,被分割成一个高度为Y(1 <= Y <= 100), 宽度为X(1 <= X <= 100)的直角网格。(1,1)是左下角的格(也就是说坐标排布跟一般的X,Y坐标相同)。乳草一开始占领了格(Mx,My)。每个星期,乳草传播到已被乳草占领的格子四面八方的每一个没有很多石头的格(包括垂直与水平相邻的和对角在线相邻的格)。1周之后,这些新占领的格又可以把乳草传播到更多的格里面了。
Bessie想要在草地被乳草完全占领之前尽可能的享用所有的牧草。她很好奇到底乳草要多久才能占领整个草地。如果乳草在0时刻处于格(Mx,My),那么会在哪个时刻它们可以完全占领入侵整片草地呢?对给定的数据总是会发生。
第0周 | 第1周 | 第2周 | 第3周 | 第4周 |
. . . . . . * . M * * . | . . . . M M * . M * * . | M M M . M M * . M * * . | M M M M M M * M M * * . | M M M M M M * M M * * M |
输入格式
* Line 1: Four space-separated integers: X, Y, Mx, and My
* Lines 2..Y+1: Line y+1 describes row (Y+2-y) of the field with X characters ('.' for grass and '*' for a boulder)
输出格式
* Line 1: A single integer that is the week number when the milkweed takes over the last remaining non-boulder square of the pasture.
输入输出样例
输入
4 3 1 1
....
..*.
.**.
输出
4
二、分析。
BFS的方法,向8个点扩展。我们可以规定一个ans值表示乳草完全侵占草原的时间。然后每次向8个方向扩展,如果这个点在地图内,这个点不是岩石,这个点没有被访问过。则我们把这个新点更新(更新位置(x, y)和步数step)并加入队列,同时还要更新最远的步数ans。当队列为空时,得到的ans值就是最后的结果。
三、AC代码:
#include <iostream>
#include <queue>
#include <algorithm>
using namespace std;
struct node {
int x, y, step;
node (int _x, int _y, int _step) {
x = _x;
y = _y;
step = _step;
}
};
int n, m, mx, my;
int sx, sy;
bool vis[105][105];
char maze[105][105];
queue<node > q;
int ans = -1;
bool in(int tx, int ty) {
return 0 <= tx && tx < n && 0 <= ty && ty < m;
}
int main() {
cin >> m >> n >> mx >> my;
for (int i = 0; i < n; i++) {
cin >> maze[i];
}
sx = n - my;
sy = mx - 1;
//bfs
q.push(node(sx, sy, 0));
vis[sx][sy] = true;
while (!q.empty()) {
node now = q.front();
q.pop();
ans = max(ans, now.step);
for (int i = -1; i <= 1; i++) { //从8个方向考虑
for (int j = -1; j <= 1; j++) {
if (i != 0 || j != 0) {
int x = now.x + i;
int y = now.y + j;
if (in(x, y) && !vis[x][y] && maze[x][y] != '*') {
q.push(node(x, y, now.step + 1));
vis[x][y] = true;
}
}
}
}
}
cout << ans << endl;
return 0;
}