题目
给你一个由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
00120
00000
00111
输出:
3
思路
遍历矿堆,如果当前值不等于0(等于1或等于2),那么从当前值计算,所有相邻的总价值是多少?
将本轮遍历产生的总价值和上次的总价值比较,得到较大值
遍历完成后,就能得到矿堆的最大价值
问题的关键在于怎么求所有相邻的总价值?根据题目描述,总价值等于=当前值+上总价值+下总价值+左总价值+右总价值。
设计 dfs(grid,i,j)函数,grid是一个二维数组,表示矿堆,(i,j)代表开始计算位置。
定义递归终止条件:如果i,j超出数组范围或者grid[i][j]==0,那么 直接返回0
定义结果res的初始值:res=grid[i][j]
递归计算与当前位置的相邻(上下左右四个位置)位置的累加价值,用res加上相邻的值
最后返回res即可
题解
package hwod;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class FindKMaxVal {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
List<String> list = new ArrayList<>();
while (sc.hasNextLine()) {
String line = sc.nextLine();
if ("".equals(line)) break;
list.add(line);
}
int n = list.size();
int[][] pile = new int[n][list.get(0).length()];
//字符数组转整形数组
for (int i = 0; i < n; i++) {
String line = list.get(i);
for (int j = 0; j < line.length(); j++) {
pile[i][j] = line.charAt(j) - '0';
}
}
System.out.println(findMaxVal(pile));
}
private static int findMaxVal(int[][] pile) {
int m = pile.length;
int res = 0;
for (int i = 0; i < m; i++) {
for (int j = 0; j < pile[i].length; j++) {
if (pile[i][j] == 1 || pile[i][j] == 2) {
int cur = dfs(i, j, pile);
res = Math.max(res, cur);
}
}
}
return res;
}
private static int dfs(int i, int j, int[][] pile) {
int m = pile.length, n = pile[0].length;
if (i >= m || j >= n || i < 0 || j < 0 || (pile[i][j] != 1 && pile[i][j] != 2)) return 0;
int res = pile[i][j];
pile[i][j] = 0;
res += dfs(i + 1, j, pile) + dfs(i, j + 1, pile) + dfs(i - 1, j, pile) + dfs(i, j - 1, pile);
return res;
}
}
推荐
如果你对本系列的其他题目感兴趣,可以参考华为OD机试真题及题解(JAVA),查看当前专栏更新的所有题目。
说明
本专栏所有文章均为原创,欢迎转载,请注明文章出处:https://blog.csdn.net/qq_31076523/article/details/134176793。百度和各类采集站皆不可信,搜索请谨慎鉴别。技术类文章一般都有时效性,本人习惯不定期对自己的博文进行修正和更新,因此请访问出处以查看本文的最新版本。