2023华为OD机试 (B卷)|200分 寻找最大价值的矿堆(Java JavaScript C++ Python)

题目描述

给你一个由'0'(空地)、'1'(银矿)、'2'(金矿)组成的地图,矿堆只能由上下左右相邻的金矿或银矿连接形成。超出地图范围可以认为是空地。
假设银矿价值1,金矿价值2,请你找出地图中最大价值的矿堆并输出该矿堆的价值。

输入描述

地图元素信息如下:

22220
00000
00000
11111

  • 地图范围最大 300*300
  • 0 <=地图元素 <= 2
输出描述

矿堆的最大价值

用例1

输入:

22220
00000
00000
01111

输出:
8

用例2

输入:

20000
00020
00000
00111

输出
3

Java
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Scanner;

public class Main {
    // 地图矩阵
    static int[][] map;

    // 上下左右,四个方向的偏移量
    static int[][] offsets = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);

        // 读入地图信息
        ArrayList<String> lines = new ArrayList<>();
        while (sc.hasNextLine()) {
            lines.add(sc.nextLine());
        }

        // 构建地图矩阵
        int rows = lines.size();
        int cols = lines.get(0).length();
        map = new int[rows][cols];
        for (int i = 0; i < rows; i++) {
            String line = lines.get(i);
            for (int j = 0; j < cols; j++) {
                map[i][j] = line.charAt(j) - '0';
            }
        }

        // 记录最大矿堆价值
        int maxVal = 0;

        // 遍历地图矩阵
        for (int i = 0; i < rows; i++) {
            for (int j = 0; j < cols; j++) {
                // 如果点(i,j)没有被访问过,且点(i,j)上有矿,则进入深搜
                if (map[i][j] > 0) {
                    LinkedList<int[]> stack = new LinkedList<>();
                    stack.add(new int[]{i, j});

                    int sum = 0;

                    while (!stack.isEmpty()) {
                        int[] pos = stack.removeLast();
                        int x = pos[0], y = pos[1];

                        sum += map[x][y];
                        map[x][y] = 0;

                        // 遍历四个方向
                        for (int[] offset : offsets) {
                            int newX = x + offset[0];
                            int newY = y + offset[1];

                            // 如果新位置在地图范围内,且有矿,则加入栈中
                            if (newX >= 0 && newX < rows && newY >= 0 && newY < cols && map[newX][newY] > 0) {
                                stack.add(new int[]{newX, newY});
                            }
                        }
                    }

                    // 更新最大矿堆价值
                    maxVal = Math.max(maxVal, sum);
                }
            }
        }

        System.out.println(maxVal);
    }
}


JavaScript
const readline = require('readline');

const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout
});

// 地图矩阵
let map;

// 上下左右,四个方向的偏移量
const offsets = [[-1, 0], [1, 0], [0, -1], [0, 1]];
let lines = [];
rl.on('line', (line) => {
  lines.push(line);
}).on('close', () => {
 // 构建地图矩阵
    const rows = lines.length;
    const cols = lines[0].length;
    map = new Array(rows);
    for (let i = 0; i < rows; i++) {
      map[i] = new Array(cols);
      const str = lines[i];
      for (let j = 0; j < cols; j++) {
        map[i][j] = parseInt(str.charAt(j));
      }
    }

    // 记录最大矿堆价值
    let maxVal = 0;

    // 遍历地图矩阵
    for (let i = 0; i < rows; i++) {
      for (let j = 0; j < cols; j++) {
        // 如果点(i,j)没有被访问过,且点(i,j)上有矿,则进入深搜
        if (map[i][j] > 0) {
          const stack = [];
          stack.push([i, j]);

          let sum = 0;

          while (stack.length > 0) {
            const pos = stack.pop();
            const x = pos[0], y = pos[1];

            sum += map[x][y];
            map[x][y] = 0;

            // 遍历四个方向
            for (const offset of offsets) {
              const newX = x + offset[0];
              const newY = y + offset[1];

              // 如果新位置在地图范围内,且有矿,则加入栈中
              if (newX >= 0 && newX < rows && newY >= 0 && newY < cols && map[newX][newY] > 0) {
                stack.push([newX, newY]);
              }
            }
          }

          // 更新最大矿堆价值
          maxVal = Math.max(maxVal, sum);
        }
      }
    }

    console.log(maxVal);
    rl.close();
})


C++
#include <iostream>
#include <vector>
#include <queue>
using namespace std;

// 地图矩阵
int map[100][100];

// 上下左右,四个方向的偏移量
int offsets[4][2] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};

int main() {
    // 读入地图信息
    vector<string> lines;
    string line;
    while (getline(cin, line)) {
        lines.push_back(line);
    }

    // 构建地图矩阵
    int rows = lines.size();
    int cols = lines[0].size();
    for (int i = 0; i < rows; i++) {
        line = lines[i];
        for (int j = 0; j < cols; j++) {
            map[i][j] = line[j] - '0';
        }
    }

    // 记录最大矿堆价值
    int maxVal = 0;

    // 遍历地图矩阵
    for (int i = 0; i < rows; i++) {
        for (int j = 0; j < cols; j++) {
            // 如果点(i,j)没有被访问过,且点(i,j)上有矿,则进入深搜
            if (map[i][j] > 0) {
                queue<pair<int, int>> q;
                q.push(make_pair(i, j));

                int sum = 0;

                while (!q.empty()) {
                    pair<int, int> pos = q.front();
                    q.pop();
                    int x = pos.first, y = pos.second;

                    sum += map[x][y];
                    map[x][y] = 0;

                    // 遍历四个方向
                    for (auto offset : offsets) {
                        int newX = x + offset[0];
                        int newY = y + offset[1];

                        // 如果新位置在地图范围内,且有矿,则加入队列中
                        if (newX >= 0 && newX < rows && newY >= 0 && newY < cols && map[newX][newY] > 0) {
                            q.push(make_pair(newX, newY));
                        }
                    }
                }

                // 更新最大矿堆价值
                maxVal = max(maxVal, sum);
            }
        }
    }

    cout << maxVal << endl;

    return 0;
}


Python
from collections import deque

# 地图矩阵
map = []

# 上下左右,四个方向的偏移量
offsets = [(-1, 0), (1, 0), (0, -1), (0, 1)]

# 读入地图信息
lines = []
while True:
    try:
        line = input()
        lines.append(line)
    except:
        break

# 构建地图矩阵
rows = len(lines)
cols = len(lines[0])
map = [[0 for j in range(cols)] for i in range(rows)]
for i in range(rows):
    line = lines[i]
    for j in range(cols):
        map[i][j] = int(line[j])

# 记录最大矿堆价值
maxVal = 0

# 遍历地图矩阵
for i in range(rows):
    for j in range(cols):
        # 如果点(i,j)没有被访问过,且点(i,j)上有矿,则进入深搜
        if map[i][j] > 0:
            stack = deque()
            stack.append((i, j))

            sum = 0

            while stack:
                pos = stack.pop()
                x, y = pos

                sum += map[x][y]
                map[x][y] = 0

                # 遍历四个方向
                for offset in offsets:
                    newX = x + offset[0]
                    newY = y + offset[1]

                    # 如果新位置在地图范围内,且有矿,则加入栈中
                    if newX >= 0 and newX < rows and newY >= 0 and newY < cols and map[newX][newY] > 0:
                        stack.append((newX, newY))

            # 更新最大矿堆价值
            maxVal = max(maxVal, sum)

print(maxVal)


  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
### 回答1: 很高兴能够参加2023华为OD(B卷)。以下是我的回答: 首先,对于我作为一名技术爱好者和计算科学专业的学生来说,华为OD是我展示自己技能和提升职业能力的绝佳会。我热爱挑战自己,希望能够通过这次来展示我的技术水平和解决问题的能力。 另外,作为一家世界知名的科技公司,华为以其创新能力和领导地位而闻名。参加华为OD,我希望能够学习到尖端的技术和最佳的工程实践。通过与华为的工程师们交流和学习,我相信我将能够进一步提升自己,掌握更多的技术和知识。 此外,参加华为OD也是为了追求个人职业发展的会。华为作为一家全球性的科技公司,有广阔的市场和众多的职业发展会。通过参加华为OD,我希望能够获得华为的认可,并有会加入华为,与卓越的团队一起工作,共同推动公司的发展和创新。 最后,我相信参加华为OD将是一次富有挑战性和有意义的经历。我会认真准备,研究和了解华为的相关业务和技术要求。我相信通过自己的努力和准备,我将能够展现出自己的实力和能力,为华为做出贡献。 总而言之,参加2023华为OD(B卷)对我而言是一个重要的会。我将全力以赴,准备充分,希望在中有出色的表现。我相信通过这次,我将能够展现自己的能力,进一步提升自己,并为华为的发展贡献力量。 ### 回答2: 2023年华为OD(B卷)是华为公司在2023年举行的一次线上。作为华为公司的OD,它将通过互联网的方式进行远程评估,为应聘者提供了参与华为招聘的会。 华为OD(B卷)相对于其他卷别可能会有一些特殊设计或者难度更高的问题。应聘者需要准备好面对各种类型的算法和编程问题,以及一些与华为相关的项目经验。 首先,准备方面,应聘者需掌握基本的数据结构和算法,熟悉常见的算法题型,如搜索、排序、动态规划等。此外,对于华为相关的项目和技术,应聘者需要了解并掌握相关的核心知识和实践经验。 其次,在过程中,要注意时间的合理安排和控制。通常时间较紧,应聘者需要快速理解问题,思考解决方案,并高效地实现代码。同时,要注重代码的可读性和优化,保证代码的正确性和效率。 最后,在OD结束后,应聘者还可以了解并掌握自己在中的不足之处,进一步提升自己的技术能力。同时,可以多关注和了解一些与华为相关的技术和行业动态,为今后的发展做好准备。 总之,参加2023华为OD(B卷)是一次宝贵的会,应聘者需要提前做好充分的准备,掌握技术知识和项目经验,合理安排时间,在中发挥自己的优势,同时也要及时总结经验教训,为未来的发展做好准备。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值