JAVA 洛谷--202110-12 数字三角形

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值