我试图解决problem #14 from Project Euler,并编写了以下C#...
int maxColl = 0;
int maxLen = 0;
for (int i = 2; i < 1000000; i++) {
int coll = i;
int len = 1;
while (coll != 1) {
if (coll % 2 == 0) {
coll = coll / 2;
} else {
coll = 3 * coll + 1;
}
len++;
}
if (len > maxLen) {
maxLen = len;
maxColl = i;
}
}
麻烦的是,它只是跑步而且似乎没有停止。
在寻找其他人解决问题的方法后,我看到一个看起来非常相似,只是他用了long而不是int。我不明白为什么这是必要的,因为这个问题所涉及的所有数字都在int的范围内,但无论如何我都试过了。
将int更改为long使代码在2秒内运行。
任何人都可以向我解释一下吗?
答案 0 :(得分:25)
当i
等于113383时,某个点的3X + 1序列超出int
的最大值,因此3 * coll + 1
溢出并变为负数:
113383→340150→...→1654740898→827370449→-1812855948→-906427974→...
最终,序列在下面的负数循环中结束:
...→-17→-50→-25→-74→-37→-110→-55→-164→-82→-41→-122→-61→-182→-91→ - 272→-136→-68→-34→-17
此循环不包含1,因此您的循环永远不会终止。
使用long
代替int
可确保coll
永不溢出。
答案 1 :(得分:24)
你的整数溢出并变为负面。
因此,你的循环永远不会终止
如果您将代码包装在checked
块中,则会看到溢出异常。
long
足以存储您需要的值,因此工作正常。