HDU3823 Prime Friend 解題報告

先線性篩出所有質數(關於線性篩,請右轉 HERE (選了篇比較好懂的博客) ),然後對所有鄰質數對進行處理。爲了方便描述,我們設一對鄰質數的差爲Ki,很明顯,Ki > 150時是毫無用處的(因爲輸入中兩個數最極端的差爲150),並且,對於每個小於等於150的Ki,只用保留較大質數小於等於150的所有鄰質數與大於150的第一對鄰質數。

有點拗口 (語文沒學好T-T) 也就是說,Ki大於150的,除了第一個,其他都不要了,因爲它們肯定不及第一個優(求的是x的最小值嘛),但是留下的都有價值 (看看代碼再仔細想想就知道了)

如果沒聽懂,再結合註釋理解理解吧

#include<cstdio>
#include<vector>
using namespace std;
#define si 13626407
//最大的有效質數是這個,輸出max(a[i][j])得到的(節約空間,人人有責)

int T;
int A, B, sum;//sum爲 已取完所有 有效素數 的Ki有幾個
bool p[si + 5];//加5免得越界
int v[887319], tot; // 1~si範圍內質數的個數+5  tot存儲目前素數個數
bool c[155];//判斷第一個大於150的並且差爲Ki的有沒有出現
vector<int> a[155];//a[Ki]存儲所有差爲Ki有效的鄰質數(較小的那個)

inline void init(){//線性篩素數
    p[1] = 1;//1不是素數
    int t;
    for ( int i = 2; i <= si; ++i ){
        if ( !p[i] ){
            v[++tot] = i;
            if ( i <= 150 ){//開始時沒加,但也可以過,數據比較水
                a[0].push_back(i);
            }else{
                if ( !c[0] ){
                    c[0] = 1;
                    a[0].push_back(i);
                }
            }
            if ( i != 2 ){
                if ( i <= 150 ) a[i - t].push_back(t);
                else{
                    if ( i - t <= 150 && !c[i - t] ){
                        c[i - t] = 1;
                        a[i - t].push_back(t);
                        sum++;
                    }
                }
            }
            t = i;
        }
        if ( sum >= 75 ) break; // Ki只可能是偶數(因爲質數除2外都是奇數,奇數減奇數爲偶數) 因此只有 150 個(當然了,除2、3外,但是這裏2和3不計入sum)
        for ( int j = 1; j <= tot; ++j )
            if ( i * v[j] <= si ) p[i * v[j]] = 1;
            else break;
    }
}

int main(){
    init();
    scanf( "%d", &T );
    for ( int I = 1; I <= T; ++I ){
        scanf( "%d%d", &A, &B );
        if ( A > B ){
            int t(A); A = B; B = t;//如果A > B 就交換 使 A <= B
        }
        int ans(-1);
        for ( int i = 0; i < a[B - A].size(); ++i ){//在所有差爲B - A的質數對中找第一個滿足條件的數
            if ( A <= a[B - A][i] ){
                ans = a[B - A][i] - A;
                break;
            }
        }
        printf( "Case %d: %d\n", I, ans );
    }
    return 0;
}

撒花(^-^)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章