spj PRIME1 Prime Generator:错误答案

SPOJ PRIME1 Prime Generator: Wrong Answer?

本文关键字:错误 答案 Generator PRIME1 Prime spj      更新时间:2023-10-16

在SPOJ上执行这个问题,尝试实现一个筛和一个分段筛来获得所需的素数。我的代码如下:

//Prime Generator
#include <iostream>
#include <math.h>
#include <cstdio>
using namespace std;
int main() {
    //traditional sieve
    int squareRoot = sqrt(1000000000);
    //printf("%dnn", squareRoot);
    bool primeList[squareRoot] = {false}; //all primes are marked as true, composite is false
    //make entire array true
    for (int i = 1; i < squareRoot; i++){
        primeList[i] = true;
    }
    //traditional sieve to find primes first
    for (int i = 2; i <= squareRoot; i++){
        for (int j = i*i; j <= squareRoot; j+=i){
            //composites are marked as false
            primeList[j - 1] = false;
        }
    }
    //segmented sieve + output
    int a;
    scanf("%d", &a);
    while (a > 0){
        int m, n;
        scanf("%d%d", &m, &n);
        //if lower than this range, then we can just output the primes we already computed
        if (n <= squareRoot){
            for (int i = m; i <= n; i++){
                if (primeList[i - 1] == true){
                    printf("%dn", i);
                }
            }
            printf("n");
        }
        //it is beyond this range, so we need to segment sieve
        else {
            int upperLimit = sqrt(n); //highest we need to divide by
            int diff = n - m;
            bool myPrimes[diff + 1];
            for (int i = 0; i <= diff; i++){
                myPrimes[i] = true;
            }
            for (int i = 2; i <= upperLimit; i++){
                if (primeList[i - 1] == true){
                    int lowest = m/i * i;
                    while (lowest < m){
                        lowest += i;
                    }
                    while (lowest <= n){
                        myPrimes[lowest - m] = false;
                        lowest += i;
                    }
                }
            }
            for (int i = m; i <= n; i++){
                if (myPrimes[i - m] == true){
                    printf("%dn", i);
                }
            }
            printf("n");
        }
        a--;
    }
}

我要做的基本逻辑是:

  1. 首先对埃拉托色尼进行筛选,生成根号下10^9的所有质数,因为10^9是n的上限。

  2. 如果n小于根号(10^9),那么我不计算任何新的东西,只是从(1)中输出适当的素数。

  3. 如果n大于sqrt(10^9),那么我首先计算sqrt(n),这是我们需要的最大数字,因为任何更大的数字在[m, n]范围内都不能被整除。

  4. 然后我将做实际的筛选,从2开始,并尝试将所有是素数的倍数的数字标记为假。我做'lowest = m/I * I '来得到最接近m的数字,其中lowest <= m。如果它低于m,那么我加到刚好高于m。例如,如果m==125, n == 200,那么125/2 = 62,62 *2 = 124。124+2 == 126,这将是[125,200]中第一个是2的倍数的数。

  5. 则输出所有未被标记为false的数字

我的问题是,似乎我的算法是正确的(对我来说)。我非常确定我的第一个筛是有效的,但似乎它在生成大于根号(10^9)的质数时可能会出现问题。然而,从我的测试来看,它似乎确实生成了所有的质数(而且只有质数)。我生成质数的算法是不是太不确定了?这是舍入的一次性问题吗?

我猜错误来自

              for (int i = 2; i <= upperLimit; i++){
                    if (primeList[i - 1] == true){
                        int lowest = m/i * i;
                        while (lowest < m){
                            lowest += i;
                        }
                        while (lowest <= n){
                            myPrimes[lowest - m] = false;
                            lowest += i;
                        }
                    }
                }

但是我不知道在哪里。欢迎任何提示或指导!

我得到了错误,它在第二种情况下,你正在定义myprime [diff] = {true}。但是想想输入的时间是怎样的M = 1且n> sqrt(1000000000)则1为质数

希望能接受你的回答。