JAVA 洛谷–202110-12 数字三角形
题目
观察下面的数字金字塔。
写一个程序来查找从最高点到底部任意处结束的路径,使路径经过数字的和最大。每一步可以走到左下方的点也可以到达右下方的点。
7
3 8
8 1 0
2 7 4 4
4 5 2 6 5
在上面的样例中,从 7→3→8→7→5 的路径产生了最大
输入格式
第一个行一个正整数 rr ,表示行的数目。
后面每行为这个数字金字塔特定行包含的整数。
输出格式
单独的一行,包含那个可能得到的最大的和。
输入输出样例
输入 #1
5
7
3 8
8 1 0
2 7 4 4
4 5 2 6 5
输出 #1
30!
解题思路
通过下图就可以知道这道题的解题思路啦!
从上往下,数组中的每个元素都加上它的左上方和上方中最大的一个数,当然,对于第一行与第二行的特殊情况需要进行单独的计算,每行的首个元素没有左上方的元素,每行的最后一个元素没有上方的元素,这些都需要小心。
a[i][j]+=max(a[i-1][j] , a[i-1][j-1]) //核心代码
附上一个只有88分的代码
import java.util.*;
public class Main {
public static void main(String[] args) {
Main t=new Main();
t.test();
}
public void test() {
int Max=0;
int [][]arr=new int[1010][1010]; //数组要开大一点,我刚开始只开了和输入的第一个数相同的长度,于是就WA了
Scanner s=new Scanner(System.in);
int r=s.nextInt();
for(int i=0;i<r;i++) {
for(int j=0;j<=i;j++) {
arr[i][j]=s.nextInt();
}
}
arr[1][0]+=arr[0][0]; //第二行的数据可以直接与第一行的数据进行相加
arr[1][1]+=arr[0][0];
for(int i=2;i<r;i++) {
arr[i][0]+=arr[i-1][0];
arr[i][i]+=arr[i-1][i-1];
for(int j=1;j<i;j++) {
if(arr[i-1][j-1]>arr[i-1][j]) { //比较 上方的数与左上方的数哪一个比较大,选择大的一个进行相加
arr[i][j]+=arr[i-1][j-1];
}
else {
arr[i][j]+=arr[i-1][j];
}
}
}
for(int i=0;i<r;i++) { //将最后一行的数据进行比较,选择最大的数据输出
if(arr[r-1][i]>Max) {
Max=arr[r-1][i];
}
}
System.out.println(Max);
}
}
提交结果显示最后一个数据MLE了,说明代码还有待优化,我受到其他大佬题解的启发,可以优化输入方式。输入方式有三种,分别是Scanner、BufferedReader、StreamTokenizer。其中效率比较的结果Scanner<BufferedReader<StreamTokenizer
最后附上一个修改后的AC代码
import java.util.*;
import java.io.*;
public class Main {
public static void main(String[] args) throws IOException {
Main t=new Main();
t.test();
}
public void test() throws IOException {
int Max=0;
int [][]arr=new int[1010][1010]; //数组要开大一点,我刚开始只开了和输入的第一个数相同的长度,于是就WA了
/*
* 利用优化的BufferReader的输入方式,效率比Scanner高
*/
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
String[] line=br.readLine().split(" ");
int r=Integer.parseInt(line[0]);
for(int i=0;i<r;i++) {
line=br.readLine().split(" ");
for(int j=0;j<=i;j++) {
arr[i][j]=Integer.parseInt(line[j]);
}
}
arr[1][0]+=arr[0][0]; //第二行的数据可以直接与第一行的数据进行相加
arr[1][1]+=arr[0][0];
for(int i=2;i<r;i++) {
arr[i][0]+=arr[i-1][0];
arr[i][i]+=arr[i-1][i-1];
for(int j=1;j<i;j++) {
if(arr[i-1][j-1]>arr[i-1][j]) { //比较 上方的数与左上方的数哪一个比较大,选择大的一个进行相加
arr[i][j]+=arr[i-1][j-1];
}
else {
arr[i][j]+=arr[i-1][j];
}
}
}
for(int i=0;i<r;i++) { //将最后一行的数据进行比较,选择最大的数据输出
if(arr[r-1][i]>Max) {
Max=arr[r-1][i];
}
}
System.out.println(Max);
}
}