我正在尝试解决Project Euler#14:
The following iterative sequence is defined for the set of positive integers:
n → n/2 (n is even)
n → 3n + 1 (n is odd)
Using the rule above and starting with 13, we generate the following sequence:
13 → 40 → 20 → 10 → 5 → 16 → 8 → 4 → 2 → 1
Which starting number, under one million, produces the longest chain?
这是我尝试过的:
public class Problem14 {
public static void main(String[] args) {
int longestLength = 1;
int longestStart = 1;
for (int i = 1; i < 1000000; i++) {
int candidate = getCollatzLength(i);
if (candidate > longestLength) {
longestLength = candidate;
longestStart = i;
}
}
System.out.println("starting point = " + longestStart);
}
public static int getCollatzLength(int startingNumber) {
int length = 1;
while (startingNumber != 1) {
startingNumber = getNextCollatz(startingNumber);
length++;
}
return length;
}
public static int getNextCollatz(int current) {
if (current % 2 == 0) {
return current / 2;
} else {
return 3 * current + 1;
}
}
}
不幸的是,这种情况持续了很长时间(超过5分钟)。知道这里出了什么问题吗?
当我打印产生当前最长链的起始编号时,我得到的最后一个是:
new longest start is 106239
答案 0 :(得分:3)
当它达到113,383时,链中的元素超过2 ^ 31-1并因此超出int
的范围,并且在达到一百万之前还有许多其他时间发生。它将在链中达到的最大值是56,991,483,520。如果您从int
更改为long
,那么您应该没问题。
答案 1 :(得分:2)
有很多冗余计算。例如,找到1,000,000的collatz序列的长度需要找到500,000的collatz序列。您应该将所有中间结果存储在数组/列表中以减少冗余。
答案 2 :(得分:0)
import java.util.*;
public class Solution {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int t = in.nextInt();
int result = 0;
int maxcount = 0;
int [] arr = new int[(int) (5 * Math.pow(10, 6) + 1)];
for(int i=2;i<=3732423;i++) {
int count = steps(i,0);
if(count > maxcount) {
result = i;
maxcount = count;
}
else if(count == maxcount) {
result = i;
}
arr[i] = result;
}
for(int a0 = 0; a0 < t; a0++){
int no = in.nextInt();
if(no > 3732423){
System.out.println(3732423);
}else{
System.out.println(arr[no]);
}
}
}
public static int steps(long num,int count) {
while(num !=1) {
if(num % 2 == 0) {
count++;
num = num / 2;
}
else {
count++;
num = num*3 + 1;
}
}
return count;
}
}