【问题标题】:Project Euler #23, can't find the issue in programProject Euler #23,在程序中找不到问题
【发布时间】:2013-04-14 05:56:07
【问题描述】:

链接:http://projecteuler.net/problem=23

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

如果一个数 n 的真因数之和为 小于n,如果这个总和超过n,则称为丰富。

因为 12 是最小的丰度数,1 + 2 + 3 + 4 + 6 = 16,所以 可以写成两个丰富数之和的最小数 是 24。通过数学分析,可以证明所有的整数 大于 28123 可以写成两个丰富数之和。 然而,这个上限不能通过分析进一步降低 即使已知最大的数是不可能的 表示为两个丰富数之和小于此限制。

求所有不能写成的正整数之和 两个丰富数之和。


问题的答案是4179871,我的程序显示3797954。

首先,我创建了一个函数,用 28124 以下的所有丰富数字填充数组丰富[]。这非常好,因为我在谷歌上搜索了丰富的数字,它们与我的数组完全匹配。

其次,我有另一个包含所有数字 1-28123 的数组,我假设所有数字“不能写为两个丰富数字的总和”。这些都写入数组hold[]。

最后,我摆脱了可以写成两个丰富数字之和的数字,方法是将丰富[]中的所有数字与丰富[]中的所有数字相加,并将保持[]的值设置为0。 (持有[丰富[0到n]+丰富[0到n]] = 0) 将所有剩余的数字加到hold[]中,我只得到3797954

我知道这个程序效率不高,因为它将所有丰富的数字添加到所有丰富的数字中,但它应该可以正常工作。它有什么问题?


#include <iostream>
#include <cmath>

using namespace std;

int hold[28124];
int abundant[7000]; //hold abundant numbers, there are only 6919 abundant numbers below 28123

bool abundance(int x){  //returns true if x is abundant
    int counter = 1;    //holds "proper divisors" of numbers, default by 1 because every int is divisible by 1
    for (int i = 2; i < sqrt(x); i++){   //finds all divisors 2 - sqrt(n)
        if (x % i == 0){
            counter += i;
            counter += x / i;
        }
    }
    int y = sqrt(x);   
    if (x % y == 0){   //adds sqrt(n) if its modulus to n is 0
            counter += sqrt(x);
        }
    if (counter > x){
        return true;
    } else {
        return false;
    }
}

int main()
{
    int counter = 0;
    for (int i = 0; i < 28124; i++){ //assumes every number cannot be written as the sum of two abundant numbers,
        hold[i] = i;                 //goes up to 28123 because "it can be shown that all integers greater
    }                                //than 28123 can be written as the sum of two abundant numbers." - project euler
    for (int j = 10; j < 28124; j++){ 
        if (abundance(j) == true){  //copies all abundant numbers up to 28123 to abundant[]
            abundant[counter] = j;
            counter++;
        }
    }

    for (int m = 0; m < counter; m++){  //adds all numbers in abundant[], with all numbers in abundant[]
        for (int n = 0; n < counter; n++){
            if (abundant[m]+abundant[n] < 28124){
                hold[abundant[m]+abundant[n]] = 0; //sum of the abundant numbers in hold[] is set to 0
            } //hold[] now holds all numbers that cannot be written as the sum of 2 abundant numbers
        }
    }
    int counter2 = 0;
    for (int x = 0; x < 28124; x++){
        counter2 += hold[x];
    }
    cout << counter2 << endl;

}

【问题讨论】:

  • 不是一个修复方法 - 但您可以通过设置一次 y = sqrt(x) 来加快处理速度,然后将 sqrt(x) 的其他实例替换为 ysqrt 是一个相当昂贵的函数...

标签: c++ perfect-numbers


【解决方案1】:

您可能会查看here 显示的代码 - 只是因为它得到了正确的答案。在不复制那里所做的事情的情况下,您可以例如确认问题出在您的丰富号码生成器中还是在其他部分。它可能会帮助您找出哪里出错了。

【讨论】:

  • 那个程序看起来和我的差不多,我看不出有什么区别,除了他有一个更有效的方法来找到丰富的金额。我试过了,但它并没有改变我的程序的结果
  • “我试过了,但它并没有改变我的程序的结果”:你是说你的代码得到了与我链接到的相同的丰富数字列表吗?如果是这样,那么@Blender 的答案不可能是正确的......但我怀疑他是(他的修复应该减少丰富数字的数量)。
  • 我没有检查所有 6919 个,但前几百个似乎是相同的。我想我需要少一点懒惰
  • 当你有一台电脑为你检查事情时,你还不如彻底。欧拉计划是关于学习的——我想你就是这么做的。 :-)
【解决方案2】:

问题出在您的abundance 函数中,特别是这部分:

int y = sqrt(x);   
if (x % y == 0){   //adds sqrt(n) if its modulus to n is 0
    counter += sqrt(x);
}

x % (int)sqrt(x) == 0 并不意味着sqrt(x) 是一个整数。一个简单的反例是 2。sqrt(2) 大约是 1.414,或者只是 1 作为整数。但是2 % 1 == 0,虽然不是平方根。

因此,要修复您的代码,请将该部分更改为:

int y = sqrt(x);   
if (y * y == x){   //adds sqrt(n) if sqrt(n) is an integer
    counter += y;
}

你会得到正确的结果。

【讨论】:

  • +1 也可以显着加快代码速度(当计数器增加时使用y 而不是sqrt(x))。
  • 我真的很感激,这让我发疯了
【解决方案3】:
my_set = set([i for i in range(1, 28123)])
print ('original sum',sum(my_set))
my_list = list(my_set)
my_l1 =[]
for k in range(12, int(my_list[-1]/2+1)):
    a = 0
    for j in range(1, int(k/2+1)):
        if k%j == 0:
            a += j
        
    if a > k:
        my_l1.append(k)
        my_set.remove(k*2)
#Calculating the sum of all the numbers which can be written as the sum of two abundant numbers   
l = 0
my_l2 = set([])
for d in my_l1:
    l += 1
    k = l
    while k < len(my_l1):
        a_s = d + my_l1[k]
        my_l2.add(a_s)
        k += 1
my_set.difference_update(my_l2)
print ('sum of all abbundant numbers:',sum(my_set))

这是我的problem23 Project Euler 的代码,这有什么问题?我现在不关心运行时,我只想要正确的答案。

蟒蛇

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-03-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-14
    • 2020-03-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多