数字三角形问题解析

对于数字三角形这个问题的要求:

题目分析:

我们可以把问题分成两部分:

1.怎么构建出来这个三角形,怎么构建才能让我下面的运算更加简单

2.如何设计程序能够使其计算出来最大的数

重点信息:向左走的次数与向右走的次数相差不能超过1

拆解分析:

怎么构建这个数字三角形?

在这个题目的输入示例中其实有一定的提示信息,示例里的三角形长这个样子:

7

3 8

8 1 0

2 7 4 4

4 5 2 6 5

这个是一个靠左的直角三角形,相较于开头的等腰三角形让我们更能想起来二维数组这一概念,空白部分只不过是没有被输入(这一点我们可以通过for循环进行控制),因此我们思路是:

以创建二维数组的方式来构建一个矩阵,再使用for循环对需要输入数据的位置进行scanf数据输入

tips:对于笔者妄图使用动态的方式进行数组创建,但忘记了数组的行列必须填入常数,而不是填入一个变量。在题干中我们也发现了提示,行数最多为100行,因此我们可以创建101行来进行数据的存储。(笔者的程序从第二行 第二列开始进行数据的填入,为了便于后期定位元素位置,且1开始进行填入更加符合认知)

如何设计程序能够使其计算出来最大的数?

我们对于寻找计算最大数的路径的方法是:

在创建三角形数组的时候(三角数组),同时也创建一个相同的二维数组用于存放各个路径下的和(加和数组)。

对于和的计算,我们选取它上级相邻的两个数中较大的一个数。

对于加和的方式我们有三种可能:

如果向下检索,检索的列在最左边,那这个位置:

该位置的加和数组的值=正上方的家和数组的值+这个位置的三角数组的值

如果向下检索过程中,检索列在该行的最右边,那个位置:

该位置的加和数组的值=上一层最右边的加和数组的值+这个位置的三角数组的值

如果向下检索过程中,检索列不在最左或者最右,那个位置:

该位置的加和数组的值=这个位置的三角数组的值+上一层相邻的两个数之间的较大值

如此方法一层层计算,加和数组也将被填满,而加和数组里的每个元素都是在当前路径下的最大和。

选择数据:

加和数组被填满后,如何选择题目要求的最大值呢?

毫无疑问的是,所谓的最大值一定在加和数组的最后一行里。

在上文的分析里,我们提到了一个重点:

重点信息:向左走的次数与向右走的次数相差不能超过1

由此推理出:

因此我们可以想象,如果是奇数行,那走的次数一定为偶数次

如果是偶数行,那走的次数一定是奇数次。

结论+数据选择方法:

因此在走奇数次时(偶数行),他们的最大值一定在加和数组里最后一行的中间两个数。

在走偶数次时(奇数行),他们的最大值一定在加和数组里最后一行里的最中间的那个数。

代码如下:

#include<stdio.h>
int main()
{
	int n = 0;
	int arr[101][101]; 
	int add[101][101];
	printf("请输入行数:");
	scanf("%d", &n);
	for (int i = 1; i <= n; i++)
	{
		for (int j = 1; j <= i; j++)
		{
			scanf("%d", &arr[i][j]);
		}
	}
	add[1][1] = arr[1][1];
	for (int i = 2; i <= n; i++)
	{
		for (int j = 1; j <= n; j++)
		{
			if (j == 1)
			{
				add[i][j] = add[i - 1][j] + arr[i][j];
			}
			else if (i == j)
			{
				add[i][j] = add[i - 1][j - 1] + arr[i][j];
			}
			else
			{
				if (arr[i - 1][j] > arr[i - 1][j - 1])
				{
					add[i][j] = arr[i][j] + add[i - 1][j];
				}
				else
				{
					add[i][j] = arr[i][j] + add[i - 1][j - 1];
				}
			}
		}
	}
	if (n % 2 == 1)
	{
		printf("max=%d \n", add[n][n / 2 + 1]);
	}
	else
	{
		if (add[n][n / 2] > add[n][n / 2 + 1])
		{
			printf("max=%d \n", add[n][n / 2]);
		}
		else
		{
			printf("max=%d \n", add[n][n / 2 + 1]);
		}
	}
	return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值