1. 程式人生 > 其它 >SP2 PRIME1 - Prime Generator,解題未遂的尤拉篩法,改用經典優化素數演算法

SP2 PRIME1 - Prime Generator,解題未遂的尤拉篩法,改用經典優化素數演算法

技術標籤:OJ+CSP+數學+技巧演算法c++cspoj素數篩

題目來自:SPOJ
當然可以在洛谷提交:https://www.luogu.com.cn/problem/SP2
題目描述
Peter wants to generate some prime numbers for his cryptosystem. Help him! Your task is to generate all prime numbers between two given numbers!

輸入格式
The input begins with the number t of test cases in a single line (t<=10). In each of the next t lines there are two numbers m and n (1 <= m <= n <= 1000000000, n-m<=100000) separated by a space.

輸出格式
For every test case print all prime numbers p such that m <= p <= n, one number per line, test cases separated by an empty line.

題意翻譯
求給定的兩個數之間的素數

Translated by @kaiming

輸入輸出樣例
輸入

2
1 10
3 5

輸出

2
3
5
7

3
5

說明/提示

Warning: large Input/Output data, be careful with certain languages (though most should be OK if the algorithm is well designed) Information

After cluster change, please consider PRINT as a more challenging problem.


我一開始打算直接用經典的開方判斷解決,但是我看到了這些:
在這裡插入圖片描述
在這裡插入圖片描述
我直接放棄了這個方法,打算實踐一下我的素數篩演算法:
錯誤程式碼如下:

#include <iostream>
#include <cmath>
#include <cstring>
using namespace std;

bool mark[1000000005];
int n, s, e;
void xxs()
{
    if (s == 1)
        s +
= 1; for (int i = 2; i <= e; i++) { if (!mark[i]) { for (int j = i * i; j <= e; j += i) mark[j] = 1; } } for (int i = s; i <= e; i++) if (!mark[i]) cout << i << " "; } int main() { // for (int i = 2; i <= 1000000005; i++) // mark[i] = 1; cin >> n; while (n--) { cin >> s >> e; memset(mark, false, sizeof(mark)); xxs(); cout << endl; } return 0; }

給我報錯RE,我一直沒檢查出來,請大佬幫忙指正。

然後我被迫使用了經典演算法,但是——TLE了,我想看看優化優化行不行。
於是我就優化成了這樣:

#include <iostream>
#include <cstring>
#include <cmath>
using namespace std;
#define LL long long
LL n, s, e;
void prime()
{
    int cnt = 0, flag = 0;
    if (s == 1)
        s += 1;
    for (int i = s; i <= e; i++)
    {
        flag = 0;
        for (int j = 2; j * j <= i; j++)
        {
            if (i % j == 0)
            {
                flag = 1;
                break;
            }
        }
        if (!flag)
        {
            cout << i << " ";
        }
    }
    cout << endl;
}
int main()
{
    cin >> n;
    for (int i = 0; i < n; i++)
    {
        cin >> s >> e;
        prime();
    }
    return 0;
}

判斷的地方優化了一下,只要i%j==0,就說明i不是素數,直接跳出迴圈繼續下一個數可以優化很多時間。除了j=1或者j=i,但這都不可能。
在這裡插入圖片描述