UVa 3n+1
问题
<!---->1.
<!---->问题描述
编号
:100.
简单描述
:
就是对一个整数
(
大于等于
1),
不断按照这样的规律进行运算
,
即如果当前数是偶数
,
则下一个数为当前数除以
2,
如果当前数为奇数
,
则下一个数为当前数乘
3
加
1,
整个过程直到计算到
1
为止
.
那么形成的数列的长度称为
cycle-length.
问题的输入是
:
给定一个区间
[a,b]
问题的输出为
:
输出给定区间
(
含端点
)
所以数的
cycle-length
的最大的
cycle-length.
详细描述可参见
这里
.
<!---->2.
<!---->问题分析
<!---->
<!---->2.1
直观分析
最直观的方法当然是采用蛮力法
(
即
brute-force),
将给定区间的每个数求出其
cycle-length,
然后在所以的
cycle-length
中找出最大的即可
.
<!---->
<!---->2.2
优化
优化是建立在分析的基础之上
.
我们先对一个简单例子进行实验
.
例如给定区间为
B[1,10],
即
1,2,3,4,5,6,7,8,9,10
通过简单分析我们可以知道
,
通常较大的数具有较大的
cycle-length,
所以我们可以首先取
A=9(
为什么不取
10,
是因为
9
在一次处理后可变为
28,
大于
10)
按照给定的规律来进行如下
:
9 28 14 7
22 11 34 17 52 26 13 40 20 10
5
16 8 4 2 1
可以看出
,
上面红色标记的部分
,
处于给定的区间内
,
而且它们的
cycle-length
显然是小于当前的数
9
的
cycle-length,
所以这些数可以从给定的区间内剔除掉
,
记住当前的
cycle-length,
于是
经过一次的操作后
,
给定的区间变为
3,6
继续按照这个方法进行
,
直至这个区间为空
,
停止
,
其中最大的
cycle-length
即为所求
.
<!---->
<!---->2.3
得出算法
算法的描述同
2.2
处优化部分的分析
,
具体的算法描述可见
3.
<!---->3.
<!---->算法描述
算法伪代码
(
类
C)
描述如下
:
function getMCL
B[left, right];
//
为给定的区间
mcl = 0;
//mcl
指
max-cycle-length
while !B.empty()
{
A = getCandidate(B);//
这个函数是用来找出
B
区间内当前最适合处理的元素
,
//
一般是最大的奇数
,
即预计可能具有较大
cycle-length
的元素
ccl = 1;
//ccl
是指
current-cycle-length
while (A!=1)
{
ccl++;
A = (A%2)?(3*A+1):(A/2);
if find(B,A)
//
这个函数是用来判断
B
区间内是否存在中间结果
A
pop(B,A);
//
有则剔除
}
mcl = (mcl<ccl)?ccl:mcl;
}
return mcl;
<!---->4.
<!---->具体实现
#include "iostream"
using namespace std;
int getCandidate(int B[], int base, int n)
{
int i;
for (i = n-1; i>=0; i--)
{
if (((base+i) % 2)&&(B[i]==0))
return i;
}
for (i = n-1; i>=0; i--)
{
if (!B[i])
return i;
}
return -1;
}
int nadd2(int left, int right)
{
int Blength = right - left + 1;
int length = Blength;
int *B = new int[length];
for (int i=0; i<length; i++)
B[i] = 0;
int mcl = 0;
while (length > 0)
{
int ccl = 1;
int pos = getCandidate(B, left, Blength);
if (pos==-1)
break;
B[pos] = 1;
length--;
int A = pos+left;
while (A!=1)
{
ccl ++;
A = (A%2)?(3*A+1):(A/2);
int Apos;
if ((A-left>Blength)||(B[A-left])||(A<left))
Apos = -1;
else
Apos = A-left;
//B[Apos] = 1;
if (Apos!=-1)
{
B[Apos] = 1;
length --;
}
}
mcl = (mcl<ccl)?ccl:mcl;
}
delete[] B;
return mcl;
}
int main()
{
int left, right;
while(cin>>left>>right)
cout<<left<<" "<<right<<" "<<nadd2(left,right)<<endl;
return 0;
}
<!----><!----><!---->
<!----><!----><!---->
<!---->5.
<!---->复杂性分析
主要的耗时部分是二层循环部分
,
而外层循环的次数主要取决于内层循环在区间内的命中率
.
没有进行过统计学的分析
,
但只要
candidate
选取合适
,
每次内层循环会有大于
50%
的命中率
.
假设区间内数
A
的内层循环次数
(
即由
A
按照规则变为
1
的
cycle-length)
为
X,
平均命中率为
p,
那么时间复杂度为
:
T(n) = X*T(n*(1-p))
//
其中
X
为平均的
cycle-length
<!---->6.
<!---->备注
在实现过程中
,
最初使用的是
C++
中的
vector,
但运行时的实际耗时比使用数组的蛮力法还要长
,
经过分析
,
这是因为编译器在维护
vector
这个数据结构时所耗时长是比较大的
,
特别是当使用
vector
的
earse
方法来删除某个特定元素时
.
所以最后还是使用最基本的数组来实现
,
用标记来指示删除状态
.
所以在实际的算法实现中
,
数据结构的选取也是非常重要的
,
所谓的程序
=
算法
+
数据结构是也
.
可以改进的地方包括有
:getCandidate
函数的算法
,
即如何预估一个具有较长
cycle-length
的元素
;
还有当内层循环出现在区间内已标记为删除状态的元素中时
,
这时内层循环可终止
.
分享到:
相关推荐
Uva 100 ,问题是The 3n+1 probelm ,可以ac的代码
UVA 100题答案
标题中的"uva272 uva272 uva272"和描述中的"uva272"指的是UVA(University of Virginia)在线判题系统的第272题,这通常与编程竞赛和算法挑战有关。该题目的标签为"算法",意味着我们需要解决一个与计算机算法设计和...
1. **算法基础**:UVa的题目中包含了各种基础算法,如排序(快速排序、归并排序、冒泡排序等)、搜索(深度优先搜索、广度优先搜索)、动态规划、贪心算法、回溯法等。掌握这些基本算法是解决大多数编程问题的基础。...
这些数据结构在UVA题目中广泛运用,例如排序、搜索、图论问题等。 2. **算法**:包括排序算法(快速排序、归并排序、堆排序等)、搜索算法(深度优先搜索DFS、广度优先搜索BFS)、动态规划、贪心策略、回溯法、分治...
1. **uva201.cpp** - 这个可能是解决UVA第201号问题的代码。由于没有具体描述,我们假设这是一个关于数据结构、排序或搜索的经典算法问题。 2. **uva202.cpp** - 同样,这可能对应UVA的第202号问题,可能涉及字符串...
通过对UVA109题目的解析可以看出,凸包构建是一个典型的计算几何问题,涉及到点排序、扫描构建以及面积计算等多个步骤。掌握好这些算法不仅能帮助解决此类题目,还能应用于更广泛的计算机科学领域中。
3. **确定三角形**:对于每个角点`j`,再遍历角点`j`之后的所有角点`k`(`j+1`到`N`),检查连接角点`j`和`k`的发光管的颜色。 4. **比较颜色**:如果连接角点`i`到`j`以及角点`j`到`k`的发光管颜色相同,则检查连接...
UVA作为训练平台,为参赛者提供了大量的实际问题,涵盖数据结构、图论、数学、排序、搜索、动态规划等多个领域。 在【压缩包子文件的文件名称列表】中提到的"UVa代码",可能包含的是对UVA题目解题思路的注释代码,...
【压缩包子文件的文件名称列表】"uva",虽然没有具体的文件名,但可以推测这些文件可能是按照UVA问题编号命名的,比如"100.cpp"、"259.py"等,代表了对应编号的UVA问题的解决方案。每个文件可能包含了特定问题的完整...
3n + 1 problem 151 - Power Crisis -> 约瑟夫问题DP 问题 10607 - Joseph's Cousin -> 约瑟夫问题变形 532 - Dungeon Master -> BFS类型的题目 299 - Train Swapping 10038 - Jolly Jumpers 10193 - All You Need ...
通过解决UVA上的问题,程序员可以提升对复杂问题的分析能力,掌握如何高效地运用数据结构和算法来解决问题。同时,这些题解也适合作为面试准备的资料,因为许多企业在招聘时都会考察候选人的算法基础。 总的来说,...
1. **基本数据类型**:了解并熟练运用整型(int)、浮点型(float)、字符串(str)和布尔型(bool)是解决问题的基础。 2. **输入与输出**:在ACM问题中,通常需要处理标准输入(stdin)和标准输出(stdout)。...
UVA是一个广受欢迎的编程竞赛网站,它为程序员提供了一个展示编程技能和解决问题的平台。这里的“不是很难,试试吧”可能意味着这些题目适合初学者或者中等水平的程序员进行训练,旨在帮助提升算法理解和编程能力。 ...
3n + 1问题 (CPE10400,UVA100) v 5, 你可以说11 (CPE10460,UVA10929) v 6, 孟加拉数字 (CPE10414,UVA10101) v 7 征服名单 (CPE21924,UVA10420) v 字元与字串 8。 什么是密码分析? ...
通过研究`test1`中的代码,我们可以看到具体是如何将这些理论知识应用于实际问题的,同时也能学习到代码的编写规范、调试技巧以及如何提高程序的运行效率。这对于提升编程能力和准备编程竞赛至关重要。 总之,"uva ...
1. **UVA在线算法竞赛平台**:理解如何在UVA平台上注册、提交代码并解决算法问题。 2. **位置代理(posAgent)**:学习如何设计和实现一个定位或路径规划算法,可能涉及图论、搜索算法(如A*算法)和动态规划。 3. *...
标签"401_palindromes"是对问题的进一步标记,方便归类和搜索,它直接关联到UVa OJ上的401号题目。 在压缩包中的文件"UVaOJ-401(Palindromes).cpp"是一个C++源代码文件,可以预见到其中包含了解决这个问题的算法...
1. **基础算法**:在UVa的题目中,你会看到基础算法的应用,如排序(冒泡、选择、插入、快速、归并排序等)、搜索(深度优先搜索DFS、广度优先搜索BFS)、动态规划、贪心策略等。这些算法是解决复杂问题的基础。 2....
uva11859nim游戏 + 求素因子个数.cpp