繁体   English   中英

小于或等于 n 的所有丰富数的总和

[英]sum of all abundant numbers less than or equal to n

问题是找到小于或等于 n 的所有丰富数的总和,其中丰富数是所有适当因数之和大于该数字的数字,例如。 12 是一个丰富的数字
1 + 2 + 3 + 4 + 6 = 16 大于 12。

这是我的实现,我得到了 TLE,我被困在这里似乎找不到任何方法。 请帮忙。

int isAbundant(int n){
int sum = 0;
for (int i=1; i<=sqrt(n); i++){
    if (n%i==0){
        if (n/i == i)
            sum = sum + i;

        else{
            sum = sum + i;
            sum = sum + (n / i);
        }
    }
}
if(sum - n > n) return 1;
else            return 0;
}

int find_abundant_numbers(int n1) {

set<int> s;

if(n1 < 12)  return 0;

for(int i = 12; i <= n1; i++){
    if(i % 2 != 0 && i < 945){
        continue;
    }
    if(s.find(i) == s.end()){
        int isA = isAbundant(i);
        if(isA){
            for(int j = 1; j * i <= n1; j++){
                s.insert(i * j);
            }
        }
    }
    else{
        continue;
    }
    //if(isA) cout << isA << " ";
}

return accumulate(s.begin(), s.end(), 0);
}

你的问题是找到一小于 n 的丰富数字,而不是检查一个特定的数字是否丰富。 以埃拉托色尼筛法为例,这是一种古老的算法,用于查找小于给定数的所有素数。 它不会逐个检查一个数字是否为质数,而是在更高级别的一系列数字上更有效地工作。

这个想法是有一个数组std::vector<int> sum(n + 1); (最初所有值都设置为 0)它会逐渐填充,直到我们获得所有数字的严格除数的所需总和。 给定一个值(除数),子过程将通过将此值添加到sum表示可被它整除的数字的所有元素(严格地)来更新数组sum

auto propagate_divisor = [&](int divisor) {
    for (int i = 2 * divisor; i <= n; i += divisor)
        sum[i] += divisor;
};

然后,我们对所有可能的值都这样做:

for (int i = 1; i <= n; ++i)
    propagate_divisor(i);

现在,随着sum的建立,我们只需要选择丰富的数字(在这里,我只是打印它们):

 for (int i = 0; i <= n; ++i)
    if (sum[i] > i)
        printf("%i ", i);

你可以在这里试试。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM