-1

我一直在解决下面的问题,但我得到了错误的答案。我的逻辑有什么问题?

完美数是一个数,其真因数之和正好等于该数。例如,28 的适当因数之和为 1 + 2 + 4 + 7 + 14 = 28,这意味着 28 是一个完美数。

一个数 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吗?

4

2 回答 2

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 和 iz,如果两者都是 true,则将值设置为 true。

3) 循环前一个数组,添加数组中所有为真的索引。

或者,“丰富”的条件是否足够稀疏,您可以将 1) 替换为丰富的数字列表和它们的哈希集。因此,不是将 j 从 1 运行到 i/2,而是循环此列表直到到达 i/2(使用哈希集快速查找 ij 是否丰富)。

无论如何,这个问题的想法是预先计算您将一次又一次使用的值,而不是一次又一次地重复isAbundant调用相同的值。

于 2013-03-17T21:54:22.360 回答
0

我会这样做:

  • 制作一个包含所有丰富数字的数组。
  • 将所有对加在一起。您可以使用嵌套for循环来做到这一点。
  • 对于添加到小于或等于 的数字的每一对,28123将该对的总和添加到总和中。
于 2013-03-17T22:10:41.360 回答