给你一个由 ‘0’ (空地)、‘1’ (银矿)、‘2’(金矿) 组成的的地图,矿堆只能由上下左右相邻的金矿或银矿连接形成。超出地图范围可以认为是空地。
假设银矿价值1,金矿价值2 ,请你找出地图中最大价值的矿堆并输出该矿堆的价值
22220 00000 00000 11111 地图范围最大 300*300 0 ≤ 地图元素 ≤ 2
22220
00000
00000
01111
8
22220
00020
00010
01111
15
20000
00020
00000
00111
3
输入矩阵的处理:
输入的矩阵由多个行组成,每行的输入是一个由数字构成的字符串(即数字矩阵),我们将其转换为二维数组(matrix)来方便处理。
广度优先搜索(BFS):
我们要使用 BFS 来遍历所有相连的区域。BFS 的作用是从某个未访问过的格子开始,遍历所有相连的格子,并累加它们的值。
相连的格子指的是那些上下左右直接相邻且其值大于 0 的格子。
每次遍历一个相连区域时,将该区域的所有格子值累加,并将它们标记为已访问(通过将值设为 0)。
最大值的计算:
每次遍历一个未访问的格子时,我们都会启动一次 BFS,计算该区域的总值,并更新最大值。
返回最大值:
最终,遍历完所有格子后,返回所有相连区域中总和最大的那个区域的值
from collections import deque
# 使用广度优先搜索(BFS)来计算一个区域的总和
def bfs(x, y, grid, rows, cols):
value = grid[x][y] # 当前格子的值
grid[x][y] = 0 # 将当前格子标记为已访问(设置为 0)
queue = deque([(x, y)]) # 初始化队列,开始 BFS
while queue:
cx, cy = queue.popleft() # 从队列中取出一个位置
# 遍历该位置的上下左右四个方向
for dx, dy in [(-1, 0), (1, 0), (0, -1), (0, 1)]:
nx, ny = cx + dx, cy + dy # 计算新位置的坐标
# 检查新位置是否在矩阵范围内,且格子的值大于 0(未访问过的格子)
if 0 <= nx < rows and 0 <= ny < cols and grid[nx][ny] > 0:
value += grid[nx][ny] # 累加新格子的值
grid[nx][ny] = 0 # 标记新格子为已访问
queue.append((nx, ny)) # 将新位置加入队列
return value # 返回当前区域的总和
# 计算矩阵中所有相连区域的最大总和
def calculateMaxValue(grid):
rows = len(grid) # 获取矩阵的行数
if rows == 0: # 如果矩阵为空,直接返回 0
return 0
cols = len(grid[0]) # 获取矩阵的列数
max_value = 0 # 用于存储最大值
# 遍历矩阵中的每一个位置
for i in range(rows):
for j in range(cols):
if grid[i][j] > 0: # 如果该位置的格子未被访问(值大于 0)
# 进行 BFS,计算当前区域的总和,并更新最大值
max_value = max(max_value, bfs(i, j, grid, rows, cols))
return max_value # 返回最大区域的总和
# 主函数:读取输入并计算最大值
matrix = [] # 存储输入的矩阵
while True:
try:
# 逐行读取输入,将每一行转换为整数列表(即矩阵的一行)
matrix.append(list(map(int, list(input()))))
except:
break # 读取完输入后退出
# 调用 calculateMaxValue 函数,输出最大区域的总和
print(calculateMaxValue(matrix))
具体解题步骤如下:
输入矩阵:
输入的数据是一个由数字组成的矩阵,每个数字代表矩阵中一个位置的权值(或者是 0 表示该格子不可访问)。
我们首先将输入的每一行数据转换成数字矩阵,然后对矩阵进行 DFS 遍历,计算每个相连区域的总和。
DFS 遍历:
从每个未访问且值大于 0 的格子开始进行 DFS,递归地访问其上下左右相邻的格子。每访问一个格子,就将其值加入当前区域的总和,并将该格子标记为已访问。
DFS 的核心思想是通过递归的方式来遍历所有与当前格子相连的格子,直到遍历完所有可达的格子。
更新最大值:
在遍历每个相连区域时,维护一个 maxWorth 变量,用于存储当前最大的区域总和。
输出最大值:
最终遍历完所有格子后,输出最大区域的总和。
import java.util.Scanner;
public class Main {
// 方向数组,表示四个方向:下、上、右、左
private static int[][] directions = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
private static boolean[][] visited; // 标记格子是否被访问过
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
// 读取输入并转换为整数矩阵
int[][] matrix = sc.tokens()
.map(line -> line.chars().map(c -> c - '0').toArray()) // 每行转为字符数组并转换为数字
.toArray(int[][]::new); // 构建二维数组
visited = new boolean[matrix.length][matrix[0].length]; // 初始化访问标记数组
int maxWorth = 0; // 存储最大区域总和
// 遍历矩阵中的每一个格子
for (int i = 0; i < matrix.length; i++) {
for (int j = 0; j < matrix[0].length; j++) {
// 如果该格子未访问过且值大于 0,则开始 DFS 计算该区域的总和
if (!visited[i][j] && matrix[i][j] > 0) {
maxWorth = Math.max(maxWorth, dfs(matrix, i, j)); // 更新最大值
}
}
}
// 输出最大区域总和
System.out.println(maxWorth);
}
// 深度优先搜索函数,计算相连区域的总和
private static int dfs(int[][] matrix, int i, int j) {
// 如果当前格子越界或已访问过,或值为 0,返回 0
if (i < 0 || i >= matrix.length || j < 0 || j >= matrix[0].length || visited[i][j] || matrix[i][j] == 0) {
return 0;
}
// 标记当前格子已访问
visited[i][j] = true;
// 当前格子的值
int worth = matrix[i][j];
// 遍历当前格子相邻的四个方向
for (int[] dir : directions) {
// 对每个相邻的格子递归调用 DFS
worth += dfs(matrix, i + dir[0], j + dir[1]);
}
// 返回当前区域的总和
return worth;
}
}
更新中
更新中
更新中
如果发现代码有用例覆盖不到的情况,欢迎反馈!会在第一时间修正,更新。
解题不易,如对您有帮助,欢迎点赞/收藏