欧拉计划 第十四题

The following iterative sequence is defined for the set of positive integers:

n → n/2 (n is even)n → 3n + 1 (n is odd)

Using the rule above and starting with 13, we generate the following sequence:

13 → 40 → 20 → 10 → 5 → 16 → 8 → 4 → 2 → 1

It can be seen that this sequence (starting at 13 and finishing at 1) contains 10 terms. Although it has not been proved yet (Collatz Problem), it is thought that all starting numbers finish at 1.

Which starting number, under one million, produces the longest chain?

NOTE: Once the chain starts the terms are allowed to go above one million.

为正整数集定义以下迭代序列:

n → n / 2(n为偶数)n →3 n + 1(n为奇数)

使用上面的规则并从13开始,我们生成以下序列:

13→40→20→10→5→16→8→4→2→1

可以看出,该序列(从13开始并在1结束)包含10个项。虽然尚未证实(Collatz问题),但认为所有起始数字都是1。

哪个起始编号低于一百万,产生最长的链?

注意:一旦链条启动允许超过一百万。

思路
1.递归求解法

(1)求每个数字的数字链长度,考虑边界条件num == 1是求到链的终点,否则返回相应的算式链并+1

(2)从1遍历到max的,不断更新ans和ans_len;

用时:3475ms

#include <stdio.h>
#include <inttypes.h>

#define max 1000000

int clain_len(int64_t num){
	if(num == 1) return 1;
	if(num % 2 == 0){
		return clain_len(num / 2) + 1;
	}else {
		return clain_len(num * 3 + 1) + 1;
	}
}
int main(){
	int ans = 0;
	int ans_len = 0;
	for(int i = 1; i < max; i++){
		int store = clain_len(i);
		if(ans_len < store){
			ans_len = store;
			ans = i;
		}
	}
	printf("%d %d\n", ans_len, ans);
	return 0;
}


2.记忆化求解法

1.记忆化:我们可以发现5->16->8->4->2->1链的长度为6;

10->5->16->8->4->2->1链的长度为7,实际上把链重新遍历了一遍

这里我们建立一个数组keep来存储遍历过的链长,这样再次查找的时候就不用多次递归调用以节省时间

2.初始化keep[keep_max] = 0;当keep[num] 不为0时,我们可以直接返回keep数组里存的链长,为0时我们更新keep

用时:125ms

#include <stdio.h>
#include <inttypes.h>

#define max 1000000
#define keep_max 5000000

int keep[keep_max + 5] = {0};

int clain_len(int64_t num){
	int ans_len = 0;
	if(num == 1) return 1;
	if(num <= keep_max && keep[num]){
		return keep[num];
	}else{
		if(num % 2 == 0){
			ans_len = clain_len(num / 2) + 1;
		}else {
			ans_len = clain_len(num * 3 + 1) + 1;
		}
	}
	if(num < keep_max){
			keep[num] = ans_len;
		}
	return ans_len;
}
int main(){
	int ans = 0;
	int ans_len = 0;
	for(int i = 1; i < max; i++){
		int store = clain_len(i);
		if(ans_len < store){
			ans_len = store;
			ans = i;
		}
	}
	printf("%d %d\n", ans_len, ans);
	return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
欧拉伯努利试是一类经典的流体力学目,常用于讨论在流体中的连续性、动量守恒和能量守恒等方面的问。使用MATLAB可以方便地求解这类问。 要解决欧拉伯努利试,我们需要使用流体力学的基本原理,即连续性方程、动量守恒和能量守恒方程。我们可以利用MATLAB编写程序,将这些方程转化为数学模型,并求解相关的物理量。 对于欧拉伯努利试,我们常常需要求解的物理量包括流速、压力和液体高度等。在MATLAB中,我们可以利用流体力学的基本原理建立方程组,并使用数值求解方法计算出相关的物理量。 以一个简单的欧拉伯努利试为例,假设流体在一段管道中流动,已知管道的截面积、液体的初始速度和液体的高度等参数。我们可以利用连续性方程、动量守恒和能量守恒方程,通过MATLAB编写程序求解出管道中的流速、压力和液体的高度等参数。 在MATLAB中,我们可以使用数值求解方法(如Euler法、Runge-Kutta法)对欧拉伯努利试进行数值求解。同时,我们还可以利用MATLAB的可视化功能,将求解结果绘制成图形,更直观地展示出物理量的变化规律。 综上所述,欧拉伯努利试是一个典型的流体力学问,在MATLAB中可以方便地使用数值求解方法求解相关的物理量,并利用可视化功能展示求解结果。通过MATLAB的应用,我们可以更深入地理解流体力学的基本原理,同时也可以更直观地展示和分析物理量的变化情况。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值