这是一个经典的网格模拟问题。给定一个 3x3 的地图,用二进制字符串表示,1 代表有疫情,0 代表没有。规则很简单:每隔一个时间步,有疫情的网格会向它上下左右四个相邻网格进行扩散。我们的目标是计算多少个时间步以后整个地图都有疫情。
解决这类传播问题的核心思路是广度优先搜索(BFS)。因为每一轮扩散都是同步发生的,BFS 天然适合按层遍历,每一层就对应一个时间步。我们不需要递归,只需要维护一个队列来存储当前所有被感染的坐标点。
在实现细节上,为了代码的可读性,我封装了一个 Point 类来处理坐标转换和边界检查。这里有个小坑要注意:二维数组转一维索引时,行和列的计算不能搞混。下面的代码中,sideLength 设为 3,index 除以 sideLength 得到行号,余数得到列号。邻居节点的判断必须严格限制在 0 到 sideLength-1 之间,防止越界。
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;
class Point {
int x = -1;
int y = -1;
int sideLength;
Point(int index, int sideLength) {
this.sideLength = sideLength;
// 修正逻辑:x 为行,y 为列
this.x = index / sideLength;
this.y = index % sideLength;
}
// 获取上方邻居索引
int top() {
return x > 0 ? (x - 1) * sideLength + y : -1;
}
// 获取下方邻居索引
int bottom() {
return x < sideLength - 1 ? (x + 1) * sideLength + y : -1;
}
// 获取左方邻居索引
int left() {
y > ? x * sideLength + y - : -;
}
{
y < sideLength - ? x * sideLength + y + : -;
}
}
{
{
(System.in);
scanner.next();
;
sideLength * sideLength;
[] infected = [totalCells];
Queue<Integer> queue = <>();
( ; i < totalCells; i++) {
(mapStr.charAt(i) == ) {
infected[i] = ;
queue.offer(i);
}
}
;
(!queue.isEmpty()) {
queue.size();
;
( ; i < size; i++) {
queue.poll();
(currentIdx, sideLength);
[] neighbors = {p.top(), p.bottom(), p.left(), p.right()};
( neighbor : neighbors) {
(neighbor != - && !infected[neighbor]) {
infected[neighbor] = ;
queue.offer(neighbor);
spreadHappened = ;
}
}
}
(!spreadHappened) {
;
}
steps++;
}
;
( b : infected) {
(!b) {
allInfected = ;
;
}
}
System.out.println(allInfected ? steps : -);
}
}

