当前位置: 首页 > news >正文

华为OD机试C卷 - 寻找最大价值矿堆 - DFS - (Java C++ JavaScript Python)

一、题目描述

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

二、输入描述

地图元素信息如:

4 5

22220

00000

00000

01111

4 表示输入数据为 4 行, 5 表示输入数据为 5 列;

地图范围最大为 300 * 300;

0<=地图元素<=2。

三、输出描述

矿堆的最大价值

四、测试用例

用例1
输入

4 5

22220

00000

00000

01111

输出

8

用例2
输入

4 5

22220

00020

00010

01111

输出

15

五、解题思路

  1. 输入处理

    • 读取行数 n 和列数 m
    • 读取 n 行字符串,构建二维字符/整数数组
  2. 建立 visited 数组,记录每个格子是否已被访问,避免重复计算

  3. 遍历每个格子

    • 如果该格子是矿(值为 1 或 2)且未被访问
    • 启动 DFS/BFS 搜索其所在的连通块(矿堆)
  4. DFS 过程

    • 标记当前格子为已访问
    • 获取当前格子价值(1 或 2)
    • 向上下左右四个方向递归,前提是:
      • 不越界
      • 未被访问
      • 是矿(即值不为 0)
    • 累加所有可达矿的价值
  5. 维护一个全局最大值,每次得到一个连通块的总价值,更新最大值

  6. 输出最大价值

六、Java源码实现

public static void main(String[] args) {// 创建 Scanner 对象用于读取标准输入Scanner sc = new Scanner(System.in);// 读取第一行输入,包含两个整数:n(行数)和 m(列数)String[] parts = sc.nextLine().trim().split("\\s+");int n = Integer.parseInt(parts[0]); // 行数int m = Integer.parseInt(parts[1]); // 列数// 创建二维数组 grid 存储地图数据:0=空地,1=银矿,2=金矿int[][] grid = new int[n][m];// 创建布尔数组 visited,记录每个格子是否已被访问(防止重复计算)boolean[][] visited = new boolean[n][m];// 读取接下来的 n 行地图数据for (int i = 0; i < n; i++) {String line = sc.nextLine().trim(); // 读取每一行字符串for (int j = 0; j < m; j++) {// 将字符 '0'/'1'/'2' 转换为对应的整数值 0/1/2grid[i][j] = line.charAt(j) - '0';}}// 关闭 Scanner(释放资源)sc.close();// 记录所有矿堆中价值最大的那个int maxVal = 0;// 遍历地图中的每一个格子for (int i = 0; i < n; i++) {for (int j = 0; j < m; j++) {// 如果当前格子未被访问,且是一个矿(值为1或2),则开始 DFS 搜索其所在的矿堆if (!visited[i][j] && grid[i][j] != 0) {int val = dfs(grid, visited, i, j); // 计算该矿堆的总价值maxVal = Math.max(maxVal, val);     // 更新最大价值}}}// 输出最大价值的矿堆的价值System.out.println(maxVal);}/*** 使用深度优先搜索(DFS)计算从 (i, j) 开始的连通矿堆的总价值* 矿堆由上下左右相邻的非空地(即值为1或2)格子组成** @param grid    地图二维数组* @param visited 访问标记数组* @param i       当前行坐标* @param j       当前列坐标* @return 当前连通矿堆的总价值*/private static int dfs(int[][] grid, boolean[][] visited, int i, int j) {// 边界检查:如果坐标越界,或该格子已被访问,或该格子是空地(0),则返回0if (i < 0 || i >= grid.length || j < 0 || j >= grid[0].length || visited[i][j] || grid[i][j] == 0) {return 0;}// 标记当前格子为已访问,避免重复访问visited[i][j] = true;// 当前格子的价值(1 或 2)int sum = grid[i][j];// 向四个方向(下、上、右、左)递归搜索相邻的矿sum += dfs(grid, visited, i + 1, j); // 向下sum += dfs(grid, visited, i - 1, j); // 向上sum += dfs(grid, visited, i, j + 1); // 向右sum += dfs(grid, visited, i, j - 1); // 向左// 返回整个连通矿堆的总价值return sum;}
运行结果

七、C++源码实现

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;// 全局变量声明(或可作为函数参数传递)
vector<vector<int>> grid;         // 存储地图数据
vector<vector<bool>> visited;     // 标记是否已访问/*** 深度优先搜索(DFS):计算从 (i, j) 出发的连通矿堆的总价值* 只有非零格子(1 或 2)且未被访问时才计入*/
int dfs(int i, int j) {int rows = grid.size();int cols = grid[0].size();// 边界检查:越界、已访问、空地(0)则返回0if (i < 0 || i >= rows || j < 0 || j >= cols || visited[i][j] || grid[i][j] == 0) {return 0;}// 标记当前格子为已访问visited[i][j] = true;// 当前格子的价值(1 或 2)int sum = grid[i][j];// 向四个方向递归搜索:下、上、右、左sum += dfs(i + 1, j); // 下sum += dfs(i - 1, j); // 上sum += dfs(i, j + 1); // 右sum += dfs(i, j - 1); // 左return sum;
}int main() {int n, m;cin >> n >> m; // 输入行数 n 和列数 m// 初始化地图和访问数组grid.assign(n, vector<int>(m, 0));          // n 行 m 列,初始为 0visited.assign(n, vector<bool>(m, false));  // 初始都未访问// 读取每一行的地图字符串for (int i = 0; i < n; i++) {string line;cin >> line; // 直接读取一整行字符(无空格)for (int j = 0; j < m; j++) {grid[i][j] = line[j] - '0'; // 字符转数字:'0'->0, '1'->1, '2'->2}}int maxVal = 0; // 记录最大矿堆价值// 遍历每个格子for (int i = 0; i < n; i++) {for (int j = 0; j < m; j++) {// 如果是矿(1 或 2)且未被访问,则进行 DFSif (!visited[i][j] && grid[i][j] != 0) {int val = dfs(i, j);maxVal = max(maxVal, val); // 更新最大值}}}// 输出结果cout << maxVal << endl;return 0;
}

八、JavaScript源码实现

/*** 主函数:读取输入,解析地图,计算最大价值矿堆*/
function main() {// 模拟输入(在 Node.js 环境中读取标准输入)const input = [];const readline = require('readline');const rl = readline.createInterface({input: process.stdin,output: process.stdout});rl.on('line', (line) => {input.push(line.trim());});rl.on('close', () => {// 第一行:n 行 m 列const [n, m] = input[0].split(/\s+/).map(Number);// 创建地图数组 grid 和访问标记数组 visitedconst grid = Array(n).fill().map(() => Array(m).fill(0));const visited = Array(n).fill().map(() => Array(m).fill(false));// 填充地图数据(从第1行到第n行)for (let i = 1; i <= n; i++) {const line = input[i];for (let j = 0; j < m; j++) {grid[i - 1][j] = parseInt(line[j], 10); // 字符转数字}}let maxVal = 0; // 记录最大矿堆价值// 遍历每个格子for (let i = 0; i < n; i++) {for (let j = 0; j < m; j++) {// 如果是矿(1 或 2)且未被访问,则进行 DFSif (!visited[i][j] && grid[i][j] !== 0) {const val = dfs(grid, visited, i, j);maxVal = Math.max(maxVal, val);}}}// 输出结果console.log(maxVal);});
}/*** 深度优先搜索(DFS):计算从 (i, j) 出发的连通矿堆的总价值* @param {number[][]} grid - 地图二维数组* @param {boolean[][]} visited - 访问标记数组* @param {number} i - 当前行* @param {number} j - 当前列* @returns {number} 连通矿堆的总价值*/
function dfs(grid, visited, i, j) {const rows = grid.length;const cols = grid[0].length;// 边界检查:越界、已访问、空地(0)则返回0if (i < 0 || i >= rows || j < 0 || j >= cols || visited[i][j] || grid[i][j] === 0) {return 0;}// 标记当前格子为已访问visited[i][j] = true;// 当前格子的价值(1 或 2)let sum = grid[i][j];// 向四个方向递归:下、上、右、左sum += dfs(grid, visited, i + 1, j); // 下sum += dfs(grid, visited, i - 1, j); // 上sum += dfs(grid, visited, i, j + 1); // 右sum += dfs(grid, visited, i, j - 1); // 左return sum;
}// 启动程序
main();

九、Python源码实现

def main():# 读取第一行:n 行 m 列n, m = map(int, input().split())# 初始化地图 grid 和访问标记数组 visitedgrid = [[0] * m for _ in range(n)]visited = [[False] * m for _ in range(n)]# 读取接下来的 n 行地图数据for i in range(n):line = input().strip()for j in range(m):grid[i][j] = int(line[j])  # 字符转整数:'0'->0, '1'->1, '2'->2max_val = 0  # 记录最大矿堆价值# 遍历每个格子for i in range(n):for j in range(m):# 如果是矿(1 或 2)且未被访问,则进行 DFSif not visited[i][j] and grid[i][j] != 0:val = dfs(grid, visited, i, j)max_val = max(max_val, val)  # 更新最大值# 输出结果print(max_val)def dfs(grid, visited, i, j):"""深度优先搜索(DFS):计算从 (i, j) 出发的连通矿堆的总价值:param grid: 二维列表,表示地图:param visited: 二维布尔列表,记录是否已访问:param i: 当前行索引:param j: 当前列索引:return: 当前连通块的总价值"""rows = len(grid)cols = len(grid[0])# 边界检查:越界、已访问、空地(0)则返回 0if i < 0 or i >= rows or j < 0 or j >= cols or visited[i][j] or grid[i][j] == 0:return 0# 标记当前格子为已访问visited[i][j] = True# 当前格子的价值(1 或 2)total = grid[i][j]# 向四个方向递归:下、上、右、左total += dfs(grid, visited, i + 1, j)  # 下total += dfs(grid, visited, i - 1, j)  # 上total += dfs(grid, visited, i, j + 1)  # 右total += dfs(grid, visited, i, j - 1)  # 左return total# 启动程序
if __name__ == "__main__":main()

http://www.dtcms.com/a/443036.html

相关文章:

  • 2025:现代硬件限制,系统设计考虑
  • 温州网站外包怎么用网站建设
  • DAY 40 训练和测试的规范写法-2025.10.4
  • 设计一个网站需要多久微信网站开放
  • 网站建设一般多少钱网址wordpress分享到qq空间
  • 外包网站设计公司天猫开店流程及费用标准多少
  • 「机器学习笔记3」机器学习常用评价指标全解析
  • 网站的建设与维护步骤360永久免费建网站
  • 佛山做网站多少钱秦皇岛网站建公司
  • Using per-item Features|使用每项特征
  • 10.Java线程的状态
  • Codeforces Round 1054 B. Unconventional Pairs(2149)
  • 如何做公众号微信杭州百度seo优化
  • 个人网站备案号可以做企业网站吗成都门户网站有哪些
  • 深圳网站建设力荐上榜网络做网站需要具备什么
  • 帝国cms网站迁移做网站杭州
  • 在线建站模板熊掌号wordpress
  • 网站可以自己建立吗黄石网站建设
  • 做网站购买服务器网站集约化平台
  • 做图片视频的网站免费域名注册 ddns
  • leetcode 36 有效的数独
  • 使用hhblits进行序列比对
  • 网站域名过期杭州网站建设哪家公司好
  • 桂林北站是哪个区wordpress 免费企业网站 模板下载
  • 逻辑门可以实现数学运算,逻辑思维与数学思维谁更基本
  • [光学原理与应用-484]:《中安DF-300S技术规格书》
  • 做的比较好的卡车网站威县做网站哪儿好
  • 安阳网站建设哪家正规温州建设小学网站首页
  • 如何做律师网站响应式网站模板html5
  • 永嘉网站建设域名年费价格表