华为OD机试E卷真题 寻找最大价值的矿堆 原题+思路+多语言代码(本题100%)(C++、Java、Py)
题目描述
给你一个由 ‘0’ (空地)、‘1’ (银矿)、‘2’(金矿) 组成的的地图,矿堆只能由上下左右相邻的金矿或银矿连接形成。超出地图范围可以认为是空地。
假设银矿价值1,金矿价值2 ,请你找出地图中最大价值的矿堆并输出该矿堆的价值。
输入描述
地图元素信息如:
22220
00000
00000
11111
- 地图范围最大 300*300
- 0 ≤ 地图元素 ≤ 2
输出描述
矿堆的最大价值
用例1
输入
22220
00000
00000
01111
输出
8
说明
用例2
输入
22220
00020
00010
01111
输出
15
说明
用例3
输入
20000
00020
00000
00111
输出
3
说明
解题思路
-
深度优先搜索(DFS):使用DFS遍历地图,找到每个矿堆,并计算其价值。
-
标记访问:使用一个二维数组来记录哪些位置已经被访问过,避免重复计算。
-
边界处理:确保在地图范围内进行搜索,超出范围的位置视为空地
代码
java
import java.util.Scanner;
public class MaxMineValue {
private static final int[][] directions = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String input = scanner.nextLine();
String[] rows = input.split("\n");
int rowsCount = rows.length;
int colsCount = rows[0].length();
int[][] map = new int[rowsCount][colsCount];
for (int i = 0; i < rowsCount; i++) {
for (int j = 0; j < colsCount; j++) {
map[i][j] = rows[i].charAt(j) - '0';
}
}
scanner.close();
boolean[][] visited = new boolean[rowsCount][colsCount];
int max = 0;
for (int i = 0; i < rowsCount; i++) {
for (int j = 0; j < colsCount; j++) {
if (map[i][j] != 0 && !visited[i][j]) {
max = Math.max(max, dfs(map, visited, i, j));
}
}
}
System.out.println(max);
}
private static int dfs(int[][] map, boolean[][] visited, int i, int j) {
if (i < 0 || i >= map.length || j < 0 || j >= map[0].length || map[i][j] == 0 || visited[i][j]) {
return 0;
}
visited[i][j] = true;
int value = map[i][j];
for (int[] dir : directions) {
value += dfs(map, visited, i + dir[0], j + dir[1]);
}
return value;
}
}
python
def max_mine_value(map_str):
rows = map_str.split('\n')
rows_count = len(rows)
cols_count = len(rows[0]) if rows_count > 0 else 0
map = [[int(c) for c in row] for row in rows]
visited = [[False for _ in range(cols_count)] for _ in range(rows_count)]
max_value = 0
directions = [(-1, 0), (1, 0), (0, -1), (0, 1)]
def dfs(i, j):
if i < 0 or i >= rows_count or j < 0 or j >= cols_count or map[i][j] == 0 or visited[i][j]:
return 0
visited[i][j] = True
value = map[i][j]
for dx, dy in directions:
value += dfs(i + dx, j + dy)
return value
for i in range(rows_count):
for j in range(cols_count):
if map[i][j] != 0 and not visited[i][j]:
current_value = dfs(i, j)
if current_value > max_value:
max_value = current_value
return max_value
def main():
import sys
input = sys.stdin.read().strip()
print(max_mine_value(input))
if __name__ == "__main__":
main()
c++
#include <iostream>
#include <vector>
#include <string>
using namespace std;
const int directions[4][2] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
int dfs(const vector<vector<int>>& map, vector<vector<bool>>& visited, int i, int j) {
if (i < 0 || i >= map.size() || j < 0 || j >= map[0].size() || map[i][j] == 0 || visited[i][j]) {
return 0;
}
visited[i][j] = true;
int value = map[i][j];
for (const auto& dir : directions) {
value += dfs(map, visited, i + dir[0], j + dir[1]);
}
return value;
}
int maxMineValue(const string& input) {
vector<string> rows;
size_t pos = 0;
string row;
while ((pos = input.find('\n')) != string::npos) {
row = input.substr(0, pos);
rows.push_back(row);
input.erase(0, pos + 1);
}
if (!input.empty()) {
rows.push_back(input);
}
int rowsCount = rows.size();
if (rowsCount == 0) return 0;
int colsCount = rows[0].size();
vector<vector<int>> map(rowsCount, vector<int>(colsCount));
for (int i = 0; i < rowsCount; i++) {
for (int j = 0; j < colsCount; j++) {
map[i][j] = rows[i][j] - '0';
}
}
vector<vector<bool>> visited(rowsCount, vector<bool>(colsCount, false));
int max_value = 0;
for (int i = 0; i < rowsCount; i++) {
for (int j = 0; j < colsCount; j++) {
if (map[i][j] != 0 && !visited[i][j]) {
int current_value = dfs(map, visited, i, j);
if (current_value > max_value) {
max_value = current_value;
}
}
}
}
return max_value;
}
int main() {
string input;
string line;
while (getline(cin, line)) {
input += line + '\n';
}
if (!input.empty()) {
input.pop_back(); // Remove the last newline character
}
cout << maxMineValue(input) << endl;
return 0;
}