【华为OD机试E卷真题】 寻找最大价值的矿堆 原题+思路+多语言代码(本题100%)(C++、Java、Py)

华为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

说明

解题思路

  1. 深度优先搜索(DFS):使用DFS遍历地图,找到每个矿堆,并计算其价值。

  2. 标记访问:使用一个二维数组来记录哪些位置已经被访问过,避免重复计算。

  3. 边界处理:确保在地图范围内进行搜索,超出范围的位置视为空地

代码

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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值