首页 > 其他 > 详细

HDU 3823 Prime Friend (打表+线性筛)

时间:2019-02-11 21:41:36      阅读:170      评论:0      收藏:0      [点我收藏+]

<题目链接>

题目大意:

已知两个数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 (打表+线性筛)

原文:https://www.cnblogs.com/00isok/p/10363237.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!