-1

以下の問題に取り組んでいますが、間違った答えが得られます。私のロジックの何が問題になっていますか?

完全数とは、その固有約数の合計がその数と正確に等しい数です。たとえば、28 の適切な約数の合計は 1 + 2 + 4 + 7 + 14 = 28 になります。つまり、28 は完全数です。

固有約数の合計が n 未満の場合、数 n は不足と呼ばれ、この合計が n を超える場合、数 n は豊富と呼ばれます。

12 は最小の豊富な数であるため、1 + 2 + 3 + 4 + 6 = 16 であるため、2 つの豊富な数の合計として記述できる最小の数は 24 です。 28123 は、2 つの豊富な数の合計として記述できます。しかし、この上限は、2 つの豊富な数の合計として表現できない最大の数がこの制限よりも小さいことがわかっているにもかかわらず、分析によってこれ以上減らすことはできません。

2 つの豊富な数の合計として書ききれないすべての正の整数の合計を求めます。

これが私のコードです:

   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;
    }
}
    }

ここで私の論理に何か問題がありますか? 2 つの豊富な数の合計として定義できる整数はすべて 0 になるのではないでしょうか?

4

2 に答える 2

0

私はこのようにします:

  • すべての豊富な数の配列を作成します。
  • すべてのペアを一緒に追加します。これは、ネストされたforループで実行できます。
  • 以下の数に追加されるすべてのペアについて28123、そのペアの合計を合計に追加します。
于 2013-03-17T22:10:41.360 に答える
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 = i となる 2 つの数値 j と k があるかどうかを知りたいとします。

あなたのコードはそれとは関係ありません。また、秒は常に 0ifであるためほとんど意味がありません。forrige

私がすること。

1) ブール値の配列 [0, 28123]。数が多い場合は true (前の手順)。(*)

2) 別の配列 [0, 28123]。位置の数が 2 つの豊富な数の加算である場合は true。i を 1 から 28123 までループし、各 i について z を 1 から i/2 までループします (j <= i/2 または k <= i / 2 のいずれか)。各 z について、前の配列で z と iz をチェックインし、両方が true の場合は値を true に設定します。

3) 前の配列をループし、配列内で true であるすべてのインデックスを追加します。

または、「豊富な」条件が十分にまばらな場合は、1) を豊富な数のリストとそれらのハッシュセットに置き換えることができます。したがって、j を 1 から i/2 まで実行する代わりに、i/2 に到達するまでこのリストをループします (ハッシュセットを使用して、ij が豊富かどうかをすばやく見つけます)。

とにかく、この問題の考え方はisAbundant、同じ値の呼び出しを何度も繰り返すのではなく、何度も使用する値を事前に計算することです。

于 2013-03-17T21:54:22.360 に答える