我一直在研究下面的问题,但我得到了错误的答案。我的逻辑出了什么问题?
完美数字是一个数字,其正确除数的总和恰好等于数字。例如,28的适当除数之和为1 + 2 + 4 + 7 + 14 = 28,这意味着28是一个完美数。
如果n的适当除数之和小于n,则n被称为不足,如果该和超过n则称为n。
由于12是最小的有限数,1 + 2 + 3 + 4 + 6 = 16,可以写成两个有限数之和的最小数是24.通过数学分析,可以看出所有大于28123的整数可以写成两个数字的总和。然而,即使知道不能表示为两个丰富数字之和的最大数量小于该限制,也不能通过分析进一步降低该上限。
找出所有正整数的总和,这些正整数不能写成两个数字的总和。
这是我的代码:
public class EulerProblem23 {
public static void main(String[] args) {
//First, I create an array containing all the numbers ranging from 1 to 28123.
int[] tall = new int[28123];
int x = 0;
for (int j = 1;j<=28123;j++){
tall[x] = j;
x++;
}
//Then, give all the numbers that can be written as the sum of two abundant numbers
//the value 0.
int forrige = 0;
for (int i = 1;i<=28123;i++){
if (isAbundant(i)){
if (2 * i <= 28123){
tall[i - 1] = 0;
}
if (forrige + i <= 28123){
tall[i - 1] = 0;
}
}
}
//All that's left should be summing all the numbers in the array.
long sum = 0;
for (int y = 0;y<28123;y++){
sum += tall[y];
}
System.out.println(sum);
}
public static boolean isAbundant(int n){
int sumAvDivisorer = 0;
for (int i = 1;i<n;i++){
if (n % i == 0){
sumAvDivisorer += i;
}
}
if (sumAvDivisorer > n){
return true;
}
else {
return false;
}
}
}
我的逻辑在这里有什么问题吗?不能将所有可以定义为两个数量之和的整数变为0吗?
答案 0 :(得分:0)
这段代码毫无意义:
//Then, give all the numbers that can be written as the sum of two abundant numbers
//the value 0.
int forrige = 0;
for (int i = 1;i<=28123;i++){
if (isAbundant(i)){
if (2 * i <= 28123){
tall[i - 1] = 0;
}
if (forrige + i <= 28123){
tall[i - 1] = 0;
}
}
}
据说,你想知道,对于循环中的每个i,如果有两个数字j和k都是丰富的,并且j + k = i。
您的代码与它无关。此外,第二个if
没有什么意义,因为forrige
始终为0。
我会做什么。
1)布尔数组[0,28123]。如果数量充足,则为真(上一步)。 (*)
2)另一个数组[0,28123]。如果位置中的数字是两个丰富数字的相加,则为真。循环i从1到28123,对于每个i,循环z从1到i / 2(j <= i / 2或k <= i / 2)。对于每个z,检查前一个数组中的z和i-z,如果两者都为真,则将值设置为true。
3)循环前一个数组并添加数组中所有的索引。
或者,“丰富”的条件是否足够稀疏,您可以用丰富的数字列表和它们的哈希集替换1)。因此,不是将j从1运行到i / 2,而是循环此列表,直到到达i / 2(使用hashset快速查找i-j是否丰富)。
无论如何,这个问题的想法是一次又一次地预先计算你将要使用的值,而不是一次又一次地重复isAbundant
次调用相同的值。
答案 1 :(得分:0)
我会这样做:
for
循环执行此操作。28123
的数字的每一对,请将该对的总和添加到总和中。