我正在研究Project Euler Problem#14,看起来我的算法运行速度非常慢。我正在尝试从2开始生成下一个Collatz编号,并在每次遇到更大的长度时替换MAX值。我似乎无法想出更好的方法来解决问题,以及如何实现它。
提前感谢您的帮助!
答案 0 :(得分:1)
而不是尝试强力方法并重新计算下一个Collatz数字,将每对数字和生成的Collatz值存储到某种数据结构中可能很有用,这样我们就可以了检查我们的评估中是否已经遇到过数字并添加其步骤而不重新计算该值。
通过这个“memoization"技术,从20评估序列可能看起来像:
20
False
10
,并将1
添加到当前路径长度True
- 程序从1开始计算,每次迭代都会增加值。7
11
。此算法的实现可能如下所示:
long long nextCollatz(long long x)
{
if (x % 2 == 0) return x / 2;
return (3 * x) + 1;
}
long long p014()
{
//key is the number, value is the end result
//check if the set contains the number before each call of nextCollatz
map<long long, int> m;
map<long long, int>::iterator it = m.begin();
long long MAX_NUM = -1;
long long VAL = 0;
int count;
for (long long i = 40; i < 1000000; i++){
count = 0;
if (m.find(i) == m.end()) //key not found (e.g. haven't generated the ending collatz number)
{
long long temp = i;
while (temp > 1)
{
count = count + 1;
temp = nextCollatz(temp); //next collatz number
if (m.find(temp) != m.end()) //found the number! we now have the ending position
{
long long val = m[temp]; //with i being the key, get the value (# of iterations needed to get to 1)
count += val; //current count + number of values to get to one
break;
}
}
if (count > MAX_NUM) {
MAX_NUM = count;
VAL = i;
}
m.insert(pair<long long, int>(i, count));
}
}
return VAL;
}