1. 程式人生 > >HDU 3823 Prime Friend (打表+線性篩)

HDU 3823 Prime Friend (打表+線性篩)

ini 一個 pro bsp names 條件 oid http algo

<題目鏈接>

題目大意:

已知兩個數a,b,求一個最小的數c,使得a+c,與b+c均為素數,並且a+c與b+c是相鄰的素數。

解題分析:
本題如果直接枚舉,很耗時間,所以我們先進行打表預處理,將所有的素數全部篩選出來(素數篩選的範圍就是相鄰素數差值大於 150 ,因為a、b均<= 150),然後枚舉所有相鄰的素數,根據它們的差值記錄下所有滿足條件的素數,然後再根據輸入的 a、b值,直接挑選出,相同差值,且大於並且最接近a、b的素數,具體過程見代碼。

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <vector> 
 4
#include <algorithm> 5 using namespace std; 6 7 #define MAXN int(2e7) //設定這個範圍需要先將素數打表看一下,滿足相鄰素數差值<=150的最大素數是多少 8 #define N int(2e6) //本題這裏的範圍卡得很嚴 9 typedef long long ll; 10 int prime[N],cnt; 11 bool isprime[MAXN+100]; 12 vector<int>vec[155]; 13 14 void GetPrime(){ //線性篩O(n)得到素數
15 cnt=0;memset(isprime,false,sizeof(isprime)); 16 for(int i=2;i<MAXN;i++){ 17 if(!isprime[i])prime[++cnt]=i; 18 for(int j=1;j<=cnt && (ll)i*prime[j] < MAXN;j++){ 19 isprime[i*prime[j]] = true; 20 if(i%prime[j]==0)break; 21 }
22 } 23 } 24 void init(){ 25 GetPrime(); 26 for(int i=0;i<=150;i++)vec[i].clear(); 27 for(int i=1;i<cnt;i++){ //記錄所有滿足差值為tmp的素數值 28 int tmp=prime[i+1]-prime[i]; 29 if(tmp<150)vec[tmp].push_back(prime[i]); 30 } 31 } 32 33 int main(){ 34 init(); 35 int T,ncase=0;scanf("%d",&T);while(T--){ 36 int a,b;scanf("%d%d",&a,&b); 37 if(a<b)swap(a,b); 38 int tmp=a-b,ans=-1; //得到a、b的差值 39 for(int i=0;i<vec[tmp].size();i++){ 40 if(vec[tmp][i]>=b){ 41 ans=vec[tmp][i]-b; 42 break; 43 } 44 } 45 printf("Case %d: %d\n", ++ncase, ans); 46 } 47 }

2019-02-11

HDU 3823 Prime Friend (打表+線性篩)