球体在线判断问题(素数发生器)

时间:2018-01-25 19:23:57

标签: c

好的,所以我喜欢使用SPOJ练习编程和开发算法。我总是对问题有疑问。很多时候,当我的代码清楚地正确回答问题时,我会收到“错误答案”的消息。如果有人能告诉我是否有什么问题,或者为什么SPOJ会告诉我我的答案是错误的,那将是非常棒的!这是逐字逐句的问题:

  

素数发生器

     

彼得想为他的密码系统生成一些素数。帮助他!你的任务是生成两个给定数字之间的所有素数!

     

输入

     

输入以单行(t)中的t<=10个测试用例开头。在下一个t行中,有两个数字mn1 <= m <= n <= 1000000000, n-m<=100000)以空格分隔。

     

输出

     

对于每个测试用例,打印所有素数p,使m <= p <= n,每行一个数字,用空行分隔的测试用例。

我的代码:

int n;
scanf("%d", &n);

if(n > 10){ return 0; }

n = n*2;
int arr[n];

for(int i = 0; i < n; i++){ scanf("%d", &arr[i]); }

for(int i = 0; i < n; i += 2){
    if(arr[i] >= 1 && arr[i] <= arr[i+1] && arr[i+1] <= 1000000000 && arr[i+1]-arr[i] <= 100000){
        for(int j = arr[i]; j <= arr[i+1]; j++){
            if(j % 2 == 1 || j == 2){
                printf("%d\n", j);
            }
        }
        printf("\n");
    }
}
return 0;

INPUT:

2
7 11
2 9

输出:

7
9
11

2
3
5
7
9

1 个答案:

答案 0 :(得分:0)

  

很多时候,我会得到一个错误的答案&#34;明确我的代码正确回答问题的消息。

这是其中一个案例,事实证明,尽管相反,你的代码似乎认为9是一个素数。这一行:

if(j % 2 == 1 || j == 2)

结合您似乎正在打印所有奇数(和两个)的事实,表明您的主要检查不正确。

你应该开始的地方是一个简单的主要检查功能,例如:

int isPrime(int num) {
    int chk = 2;
    while (chk * chk <= num)
        if ((num % chk) == 0)
            return 0;
        ++chk;
    }
    return 1;
}

一旦你有了它,然后担心性能(我最喜欢的两个咒语是&#34;错误的是最少优化状态&#34;和&# 34;让它先工作,然后让它快速工作&#34;)。

您可以查看优化的内容包括但不限于:

  • Eratosthenes筛子在哪里,如果质数范围不是太大,它可以通过不必对每个主要测试进行大量计算来大大提高速度;和
  • 使用除了两个和三个以外的所有素数都具有6n±1形式的事实,有效地使isPrime函数的速度增加三倍(请参阅here以获得解释)。

对于第二个要点,您可以使用:

int isPrime(unsigned int num) {
    // Special cases for 0-3.

    if (num < 2) return 0;
    if (num < 4) return 1;

    int chk = 5, add = 2;         // prime generator, 6n +/- 1.
    while (chk * chk <= num)      // check every candidate.
        if ((num % chk) == 0)     // check if composite.
            return 0;
        chk += add;               // next candidate.
        add = 6 - add;            // alternate +2, +4.
    }
    return 1;                     // no factors, must be prime.
}