第七届蓝桥杯省赛Java语言_冰雹数

冰雹数

任意给定一个正整数N,
如果是偶数,执行: N / 2
如果是奇数,执行: N * 3 + 1

生成的新的数字再执行同样的动作,循环往复。

通过观察发现,这个数字会一会儿上升到很高,
一会儿又降落下来。
就这样起起落落的,但最终必会落到“1”
这有点像小冰雹粒子在冰雹云中翻滚增长的样子。

比如N=9
9,28,14,7,22,11,34,17,52,26,13,40,20,10,5,16,8,4,2,1
可以看到,N=9的时候,这个“小冰雹”最高冲到了52这个高度。

输入格式:
一个正整数N(N<1000000)
输出格式:
一个正整数,表示不大于N的数字,经过冰雹数变换过程中,最高冲到了多少。

例如,输入:
10
程序应该输出:
52

再例如,输入:
100
程序应该输出:
9232

资源约定:
峰值内存消耗(含虚拟机) < 256M
CPU消耗  < 1000ms


请严格按要求输出,不要画蛇添足地打印类似:“请您输入...” 的多余内容。

所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。
注意:不要使用package语句。不要使用jdk1.7及以上版本的特性。
注意:主类的名字必须是:Main,否则按无效代码处理。

解析:

       此题需要注意题目要求的是“不大于N的数字,经过冰雹数变换过程中,最高冲到了多少。”,有许多人没有看清这个要求,所以一直在犯迷糊。本题要算出答案不难,但是容易超时,题目给出的时间限制是1000ms,如果用普通的方法去做,那么需要7秒才能运算出答案。我采用的方法是打表法(边算边打),由于N<1000000所以我定义了一个长度我1000001的long型数组,打算用冰雹数对应数组的下标。在1~N的循环中,每次求出一个冰雹数的最大高度,就将下标为冰雹数的数组值设为最大高度,然后在while循环中只需判断当前冰雹数对应的数组值是否为0,如果不为0,就代表该冰雹数的最大高度已经算出来了,接着将该值与当前的最大值(max)进行比较,然后就可以跳出while循环了。如果为0,就继续循环下去。

源代码如下:

import java.util.Scanner;

/**
 * 时间比较:打表法用时1秒,普通法用时7秒。
 */
public class 冰雹数 {

	public static void main(String[] args) {
		Scanner input = new Scanner(System.in);
		long arr[] = new long[100 * 10000 + 1];
		while (input.hasNext()) {
			long n = input.nextLong();

			long tmp = n;
			long res = 0;
			for (int i = 1; i <= tmp; i++) {
				long max = i;
				n = i;
				
				while (n != 1) {
					if (n < arr.length) {
						if (arr[(int) n] != 0) {
							if (arr[(int) n] > max) {
								max = arr[(int) n];
							}

							break;
						}
					}
					if (n % 2 == 0) {
						n /= 2;
					} else {
						n = n * 3 + 1;
					}
					if (n > max) {
						max = n;
					}

				}

				arr[i] = max;
				if (max > res) {
					res = max;
				}
			}
			System.out.println(res);
		}

	}

}

吐舌头

<think>好的,我现在要解决用户关于蓝桥杯冰雹猜想题目的问题。首先,我需要回忆冰雹猜想的基本概念。冰雹猜想,也就是科拉兹猜想,指的是对于任意正整,如果是偶就除以2,如果是奇就乘以3加1,最终都会回到1。题目通常要求找出在某个范围内的经过这个变换过程中的最大值。 用户提到的引用中,引用[4]和[5]直接相关。特别是引用[4]中的代码示例,展示了如何遍历不大于N的所有,计算每个变换过程中的最大值,并最终输出最大的那个。这里的关键点是,对于每个,要一直计算直到它变为1,并记录过程中的最大值。例如,输入N=9时,最大的是52,这发生在计算到某个的时候。 用户可能遇到的陷阱是题目中的“不大于N的正整”指的是从1到N的所有,而每个都需要单独处理,找到各自变换路径中的最大值,然后在这些最大值中取最大的。比如当N=10时,需要考虑的是1到10的所有,每个变换路径中的最大值,然后找出最大的那个。根据引用[4],当N=9时,输出是52,所以当输入N=10时,可能最大的还是出现在某个的变换路径中,比如可能是9的路径中的52。 解题思路应该是这样的:首先遍历从2到N的每个(因为1的路径最大值就是1),对每个进行冰雹变换,记录过程中的最大值,最后比较所有的最大值,输出最大的那个。需要注意的是,在变换过程中,即使当前超过了N,也需要继续计算,直到变为1,因为可能存在中间值比N大的情况,比如当N=9时,某个的变换过程中会出现52。 在代码实现上,可以使用循环或者递归。例如,引用[4]中的C代码使用了循环,对于每个temp,不断应用规则,直到temp变为1,同时更新max。Python的实现可以类似,遍历每个,进行循环处理,记录最大值。 用户可能的问题是关于如何处理大时的效率,或者如何避免重复计算。但根据题目给出的例子,可能不需要特别优化,因为N的范围可能不大。比如引用[4]中的代码处理到N=1e6的情况,但需要确保算法的时间复杂度在合理范围内。 总结一下,解题步骤是: 1. 遍历每个i从2到N。 2. 对每个i,进行冰雹变换,直到变为1,记录过程中的最大值。 3. 比较所有i的最大值,输出全局最大值。 现在需要确保代码正确处理奇偶情况,并且在每个的变换过程中正确更新最大值。例如,当i=3时,变换序列是3→10→5→16→8→4→2→1,最大值为16。而像i=7时,变换路径会更长,中间可能产生更大的值,需要正确捕捉到这些情况。 此外,用户提到的输入10输出52的情况,可能是因为当i=9时,其变换路径中的最大值是52,而其他的路径中的最大值都不超过这个,所以最终输出52。因此,正确遍历每个并计算其路径的最大值是关键。 最后,根据这些分析,可以写出相应的Python代码,并验证是否正确处理了这些情况。</think>### 蓝桥杯冰雹猜想题目解析 冰雹猜想(科拉兹猜想)要求对任意正整$N$,按以下规则变换: - 若$N$为偶,则$N \leftarrow N/2$ - 若$N$为奇,则$N \leftarrow 3N+1$ 最终必会回到1。蓝桥杯相关题目通常要求**找出不大于$N$的所有正整变换过程中出现的最大值**[^4][^5]。 --- ### 解题思路与代码实现 **题目示例**: - 输入:$N=9$ - 输出:52 解释:当遍历$2$到$9$的所有时,某次变换过程中会达到最大值52(如$i=9$的变换路径)[^1]。 **关键步骤**: 1. **遍历所有**:对$2 \leq i \leq N$的每个执行冰雹变换。 2. **记录路径最大值**:在变换过程中跟踪当前的路径最大值。 3. **更新全局最大值**:比较所有路径的最大值,保留最大的一个。 **Python代码实现**: ```python def hailstone_max(N): max_val = 0 for i in range(2, N + 1): current = i while current != 1: if current % 2 == 0: current //= 2 else: current = current * 3 + 1 if current > max_val: max_val = current return max_val N = int(input()) print(hailstone_max(N)) ``` **代码解析**: - `max_val`记录全局最大值。 - 外层循环遍历所有起始$i$(从2到$N$)。 - 内层循环执行冰雹变换,直到$current=1$,并更新路径中的最大值。 - 最终返回全局最大值。 --- ### 常见陷阱与优化 1. **陷阱**:题目要求“不大于$N$的正整”包括所有$1 \leq i \leq N$,但$i=1$的路径只有1,因此从$i=2$开始遍历即可。 2. **优化**:若某次变换中$current$已小于当前起始$i$,可提前终止循环(因之前的已计算过该路径)[^4]。 ---
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值