【转】UVa Problem 100 The 3n+1 problem (3n+1 问题)——(离线计算)

2023-10-12 21:50

本文主要是介绍【转】UVa Problem 100 The 3n+1 problem (3n+1 问题)——(离线计算),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

  1 // The 3n+1 problem (3n+1 问题)
  2 // PC/UVa IDs: 110101/100, Popularity: A, Success rate: low Level: 1
  3 // Verdict: Accepted
  4 // Submission Date: 2011-05-22
  5 // UVa Run Time: 0.032s
  6 //
  7 // 版权所有(C)2011,邱秋。metaphysis # yeah dot net。
  8 //
  9 // [问题描述]
 10 // 考虑如下的序列生成算法:从整数 n 开始,如果 n 是偶数,把它除以 2;如果 n 是奇数,把它乘 3 加
 11 // 1。用新得到的值重复上述步骤,直到 n = 1 时停止。例如,n = 22 时该算法生成的序列是:
 12 //
 13 // 22,11,34,17,52,26,13,40,20,10,5,16,8,4,2,1
 14 //
 15 // 人们猜想(没有得到证明)对于任意整数 n,该算法总能终止于 n = 1。这个猜想对于至少 1 000 000
 16 // 内的整数都是正确的。
 17 //
 18 // 对于给定的 n,该序列的元素(包括 1)个数被称为 n 的循环节长度。在上述例子中,22 的循环节长度
 19 // 为 16。输入两个数 i 和 j,你的任务是计算 i 到 j(包含 i 和 j)之间的整数中,循环节长度的最大
 20 // 值。
 21 //
 22 // [输入]
 23 // 输入每行包含两个整数 i 和 j。所有整数大于 0,小于 1 000 000。
 24 //
 25 // [输出]
 26 // 对于每对整数 i 和 j,按原来的顺序输出 i 和 j,然后输出二者之间的整数中的最大循环节长度。这三
 27 // 个整数应该用单个空格隔开,且在同一行输出。对于读入的每一组数据,在输出中应位于单独的一行。
 28 //
 29 // [样例输入]
 30 // 1 10
 31 // 100 200
 32 // 201 210
 33 // 900 1000
 34 //
 35 // [样例输出]
 36 // 1 10 20
 37 // 100 200 125
 38 // 201 210 89
 39 // 900 1000 174
 40 //
 41 // [解题方法]
 42 // 计算每个数的循环节长度,求给定区间的最大值。
 43 //
 44 // 需要注意:
 45 // 1. 中间计算过程会超过 int 或 long (如果 int 或 long 型均为 4 字节存储空间) 型数据所能
 46 //    表示的范围,故需要选择 long long (8 字节存储空间)型整数(除非你使用的算法在做乘的时候不
 47 //    使用一般的乘法,而是使用替代方法实现原数的三倍加一)。
 48 // 2. 输入时可能较大的数在前面,需要调整顺序,这个是导致算法正确却 WA 的重要原因。
 49 // 3. 采用填表的方法保存既往计算结果,可以显著减少计算时间。
 50 //
 51 // 从网络上看了许多别人的解题方案,大多数都是忽略了第一点,求循环节长度的过程中,选择了 int 或
 52 // long (按 32 位 CPU 来假定,4 字节存储空间)类型的数据,当计算 (n * 3 + 1) 时会超出 32
 53 // 位整数的表示范围而得到错误答案,只不过 Programming Challenges 和 UVa 上的测试数据不是很强,
 54 // 所以尽管不完善但都会获得 AC。在 1 - 999999 之间共有 41 个数在中间计算过程中会得到大于 32 位
 55 // 无符号整数表示范围的整数,当测试数据包含这些数时,选用 int 或 long 类型有可能会得到错误的答案。
 56 //
 57 // 在中间计算过程中会超过 32 位整数表示范围的整数(括号内为循环节长度):
 58 // 159487(184)  270271(407)  318975(185)  376831(330)  419839(162)
 59 // 420351(242)  459759(214)  626331(509)  655359(292)  656415(292)
 60 // 665215(442)  687871(380)  704511(243)  704623(504)  717695(181)
 61 // 730559(380)  736447(194)  747291(248)  753663(331)  763675(318)
 62 // 780391(331)  807407(176)  822139(344)  829087(194)  833775(357)
 63 // 839679(163)  840703(243)  847871(326)  859135(313)  901119(251)
 64 // 906175(445)  917161(383)  920559(308)  937599(339)  944639(158)
 65 // 945791(238)  974079(383)  975015(321)  983039(290)  984623(290)
 66 // 997823(440)
 67     
 68 #include <iostream>
 69     
 70 using namespace std;
 71 
 72 #define min(a, b) ((a) <= (b) ? (a) : (b))
 73 #define max(a, b) ((a) >= (b) ? (a) : (b))
 74 
 75 #define MAXSIZE 1000000
 76     
 77 int cache[MAXSIZE];
 78 
 79 // 计算循环节长度。
 80 int counter(long long number)
 81 {
 82     if (number == 1)
 83         return 1;
 84     
 85     // 模 2 计算可用与计算代替,除 2 计算可用右移计算代替。
 86     if (number & 1)
 87         number += (number << 1) + 1;
 88     else
 89         number >>= 1;
 90     
 91     // 若 number 在缓存范围内则根据情况取用。
 92     if (number < MAXSIZE )
 93     {
 94         if (!cache[number])
 95             cache[number] = counter(number);
 96         return 1 + cache[number];
 97     }
 98     
 99     return 1 + counter(number);
100 }
101     
102 int main(int ac, char *av[])
103 {
104     // 对于 GUN C++ 编译器,使用默认参数,在编译时会自动将全局数组 cache 中未初始化
105     // 的元素初始化为 0,故可以不需要显式的进行初始化的工作。对于其他编译器应该根据情况调整。
106     //
107     // memset(cache, 0, sizeof(cache));
108     //
109     int first, second, start, end;
110 
111     while (cin >> first >> second)
112     {
113         // 得到给定范围的上下界。
114         start = min(first, second);
115         end = max(first, second);
116         
117         // 查找最大步长值。
118         int result = 0, steps;
119         for (int i = start; i <= end; i++)
120             if ((steps = counter(i)) > result)
121                 result = steps;
122 
123         // 输出。
124         cout << first << " " << second << " " << result << endl;
125     }
126     
127     return 0;
128 }
View Code

 

来自csdn博客,作者寂静山林,链接:http://blog.csdn.net/metaphysis/article/details/6431937

转载于:https://www.cnblogs.com/huashanqingzhu/p/4045115.html

这篇关于【转】UVa Problem 100 The 3n+1 problem (3n+1 问题)——(离线计算)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/198693

相关文章

springboot循环依赖问题案例代码及解决办法

《springboot循环依赖问题案例代码及解决办法》在SpringBoot中,如果两个或多个Bean之间存在循环依赖(即BeanA依赖BeanB,而BeanB又依赖BeanA),会导致Spring的... 目录1. 什么是循环依赖?2. 循环依赖的场景案例3. 解决循环依赖的常见方法方法 1:使用 @La

SpringBoot启动报错的11个高频问题排查与解决终极指南

《SpringBoot启动报错的11个高频问题排查与解决终极指南》这篇文章主要为大家详细介绍了SpringBoot启动报错的11个高频问题的排查与解决,文中的示例代码讲解详细,感兴趣的小伙伴可以了解一... 目录1. 依赖冲突:NoSuchMethodError 的终极解法2. Bean注入失败:No qu

MySQL新增字段后Java实体未更新的潜在问题与解决方案

《MySQL新增字段后Java实体未更新的潜在问题与解决方案》在Java+MySQL的开发中,我们通常使用ORM框架来映射数据库表与Java对象,但有时候,数据库表结构变更(如新增字段)后,开发人员可... 目录引言1. 问题背景:数据库与 Java 实体不同步1.1 常见场景1.2 示例代码2. 不同操作

如何解决mysql出现Incorrect string value for column ‘表项‘ at row 1错误问题

《如何解决mysql出现Incorrectstringvalueforcolumn‘表项‘atrow1错误问题》:本文主要介绍如何解决mysql出现Incorrectstringv... 目录mysql出现Incorrect string value for column ‘表项‘ at row 1错误报错

如何解决Spring MVC中响应乱码问题

《如何解决SpringMVC中响应乱码问题》:本文主要介绍如何解决SpringMVC中响应乱码问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Spring MVC最新响应中乱码解决方式以前的解决办法这是比较通用的一种方法总结Spring MVC最新响应中乱码解

pip无法安装osgeo失败的问题解决

《pip无法安装osgeo失败的问题解决》本文主要介绍了pip无法安装osgeo失败的问题解决,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一... 进入官方提供的扩展包下载网站寻找版本适配的whl文件注意:要选择cp(python版本)和你py

解决Java中基于GeoTools的Shapefile读取乱码的问题

《解决Java中基于GeoTools的Shapefile读取乱码的问题》本文主要讨论了在使用Java编程语言进行地理信息数据解析时遇到的Shapefile属性信息乱码问题,以及根据不同的编码设置进行属... 目录前言1、Shapefile属性字段编码的情况:一、Shp文件常见的字符集编码1、System编码

Spring MVC使用视图解析的问题解读

《SpringMVC使用视图解析的问题解读》:本文主要介绍SpringMVC使用视图解析的问题解读,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Spring MVC使用视图解析1. 会使用视图解析的情况2. 不会使用视图解析的情况总结Spring MVC使用视图

Redis解决缓存击穿问题的两种方法

《Redis解决缓存击穿问题的两种方法》缓存击穿问题也叫热点Key问题,就是⼀个被高并发访问并且缓存重建业务较复杂的key突然失效了,无数的请求访问会在瞬间给数据库带来巨大的冲击,本文给大家介绍了Re... 目录引言解决办法互斥锁(强一致,性能差)逻辑过期(高可用,性能优)设计逻辑过期时间引言缓存击穿:给

Java程序运行时出现乱码问题的排查与解决方法

《Java程序运行时出现乱码问题的排查与解决方法》本文主要介绍了Java程序运行时出现乱码问题的排查与解决方法,包括检查Java源文件编码、检查编译时的编码设置、检查运行时的编码设置、检查命令提示符的... 目录一、检查 Java 源文件编码二、检查编译时的编码设置三、检查运行时的编码设置四、检查命令提示符