【问题标题】:Project Euler #10 How to pre-calculate sum of primes?Project Euler #10 如何预先计算素数之和?
【发布时间】:2015-06-14 15:16:49
【问题描述】:

问题来了:

10以下的素数之和为2+3+5+7=17。

求所有不大于给定 N 的素数之和。

输入格式: 第一行包含一个整数 T,即测试用例的数量。 接下来的 T 行将包含一个整数 N。

输出格式: 单独打印每个测试用例对应的值。

约束: 1≤T≤104 1≤N≤106

https://www.hackerrank.com/contests/projecteuler/challenges/euler010 这是问题的链接。

所以,我尝试使用 Eratosthenes 筛解决这个问题。 我预先计算了低于 10^6 的所有素数,这是 N 的给定限制。

7 个测试用例中有 6 个被接受,但最后一个测试用例给出 Timeout(TLE)。

我阅读了论坛,他们说为了解决这个问题,我们还需要预先计算素数和。

所以,我尝试制作一个 long long int 数组并尝试将所有总和存储在其中。但这给了我一个分段错误。

那么,我应该如何预先计算素数之和?

这是我的代码:

#include "header.h"             //MAX is defined to be 1000000

bool sieve[MAX + 1];        // false = prime, true = composite

int main(void){
    //0 and 1 are not primes
    sieve[0] = sieve[1] = true;
    //input limiting value
    int n = MAX;
    //cross out even numbers
    for(int i = 4; i <= n; i += 2){
        sieve[i] = true;
    }
    //use sieve of eratosthenes
    for(int i = 3; i <= static_cast<int>(sqrt(n)); i += 2){     
        if(sieve[i] == false){                          
            for(int j = i * i; j <= n; j += i)              
                sieve[j] = true;
        }
    }
    long long p, ans = 0;
    int t;
    std::cin >> t;
    while(t--){
        std::cin >> p;
        for(int i = 0; i <= p; ++i)
            if(sieve[i] == false)
                ans += i;
        std::cout << ans << std::endl;
        ans = 0;
    }
    return 0;
}

【问题讨论】:

  • 您是否在调试器中看到了出现分段错误的点?
  • 对筛子使用 bitset 而不是 int 数组

标签: c++ c++11 primes sieve-of-eratosthenes


【解决方案1】:

给定素数数组prime[N],可以在单个for 循环中预先计算素数和,如下所示:

int sum[N];
sum[0] = primes[0];
for (int i = 1 ; i < N ; i++) {
    sum[i] = prime[i]+sum[i-1];
}

您可以将此数组与primes[] 一起使用,方法是在primes 上运行二进制搜索,如果要搜索的数字是素数,则在相同位置选择sum,如果数字是素数,则在前一个位置不是素数。

【讨论】:

  • 嗯,好的,我会试试的。但是为什么会出现分段错误?此外,鉴于问题中 N 的限制,我认为我将需要一个 long long int 数组。
猜你喜欢
  • 2012-03-11
  • 2021-07-21
  • 1970-01-01
  • 1970-01-01
  • 2010-12-31
  • 2017-01-01
  • 2012-07-20
  • 1970-01-01
  • 2014-05-26
相关资源
最近更新 更多