我遇到以下问题(来自ProjectEuler.net - Problem 14)
为正整数集定义了以下迭代序列:
n -> n/2 (n is even)
n -> 3n + 1 (n is odd)
使用上面的规则并从13开始,我们生成以下序列:
13 → 40 → 20 → 10 → 5 → 16 → 8 → 4 → 2 → 1
可以看出,此序列(从13
开始,在1
处结束)包含10个术语。虽然尚未证实(Collatz问题),但据认为所有起始数字都在1
完成。
哪个起始编号低于一百万,产生最长的链?
注意:一旦链条启动,条款允许超过一百万。
我用过:
static int road (int n)
{
int road = 0;
while (n != 1)
{
if (n % 2 == 0)
n = n / 2;
else
n = 3 * n + 1;
road++;
}
return road;
}
static void Main(string[] args)
{
int max = 0, num = 0;
for (int i = 1; i < 1000000; i++)
{
if (road(i) > max)
{
max = road(i);
num = i;
}
}
Console.WriteLine(num);
}
但是没有打印输出。
答案 0 :(得分:11)
(我不打算给你一个完整的解决方案,因为Project Euler打算你思考,而不是已经解决了问题的我们。) 子>
尝试计算链中的值的大小,并牢记limits for integral types。
答案 1 :(得分:1)
function problem14(){
function r(p,n){
return cl(p)>cl(n)?p:n;
}
function c(n){
return n%2===0?n/2:3*n+1;
}
function cl(n){
var _a = 1;
var _n = n;
while(_n !== 1){
_a++;
_n = c(_n);
}
return _a;
}
var b = [];
var m = 20;
var i = 500000;
while(i < 1000000){
var _n = cl(i);
if(_n>m){
b.push(i);
m = _n;
}
i++;
}
return b.reduce(r);
}
这是我的js代码。
答案 2 :(得分:0)
不是“没有输出”,它只是运行很长时间。如果将for循环的上限更改为100000,您将很快看到输出。它运行很长的原因是你使用未经检查的整数,并且你不应该在你想要的地方获得溢出。几秒后休息,你会看到一个负面的n
。
尝试以下操作,即使用checked
关键字,它会说明我的意思:
// will now throw OverflowException with large n
checked
{
int road = 0;
while (n != 1)
{
if (n%2 == 0)
n = n/2;
else
n = 3*n + 1;
road++;
}
return road;
}
答案 3 :(得分:0)
首先,请注意您每次迭代都会调用road()函数两次,这会浪费处理时间(对于“带有副作用的函数”,可能会产生不必要的后果)。
其次,由于整数溢出,你无法得到答案 - 例如,值113383最终以相同的20个左右的数字循环
-122,-61,-182,-91,-272,-136,-68,-34,-17,-50,-25,-74,-37,-110,-55, - 164,-82,-41,-122
糟糕!