【问题标题】:abundant sums, logic丰富的总和,逻辑
【发布时间】:2015-01-23 01:25:22
【问题描述】:

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

完美数是一个数,它的真因数之和正好等于这个数。例如,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吗?

【问题讨论】:

  • forrige 是干什么用的? i 将始终小于或等于 28123,因此您将数组中的所有值设置为 0
  • @Blender:不,我没有。 forrige 是在for循环中获取之前的值。我的数组中的所有值都没有设置为 0,这是不正确的。
  • 哦,废话,对不起,你是对的。我忘了在循环结束时设置 forrige = i。
  • 我似乎仍然得到了错误的答案,尽管forrige = i 设置在循环的末尾。
  • 您的代码如何检查一个数字是否是任何两个小于 28123 的丰富数字之和?

标签: java arrays perfect-numbers


【解决方案1】:

我会这样做:

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

【讨论】:

    【解决方案2】:

    这段代码没有意义:

    //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

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

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

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

    【讨论】:

    • 从数学上讲,我不能这样: 1. 找到丰富的数字 2. 将它乘以 2。该数字是两个丰富数字的总和。 3.将丰富的数字添加到之前的丰富数字中。该数字是两个丰富数字的总和。我没有看到该逻辑中的错误。
    • 按照你的解释,你会发现一些个数是两个丰富数之和。这不是被问到的。你必须确保你做出所有可能的总和
    猜你喜欢
    • 2011-08-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-11
    • 1970-01-01
    • 1970-01-01
    • 2011-07-27
    相关资源
    最近更新 更多