HDU 3823 Prime Friend

来源:互联网 发布:网络报纸 编辑:程序博客网 时间:2024/06/05 07:23

Prime Friend

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 3325    Accepted Submission(s): 673


Problem Description
Besides the ordinary Boy Friend and Girl Friend, here we define a more academic kind of friend: Prime Friend. We call a nonnegative integer A is the integer B’s Prime Friend when the sum of A and B is a prime.
So an integer has many prime friends, for example, 1 has infinite prime friends: 1, 2, 4, 6, 10 and so on. This problem is very simple, given two integers A and B, find the minimum common prime friend which will make them not only become primes but also prime neighbor. We say C and D is prime neighbor only when both of them are primes and integer(s) between them is/are not.
 

Input
The first line contains a single integer T, indicating the number of test cases.
Each test case only contains two integers A and B.

Technical Specification

1. 1 <= T <= 1000
2. 1 <= A, B <= 150
 

Output
For each test case, output the case number first, then the minimum common prime friend of A and B, if not such number exists, output -1.
 

Sample Input
22 43 6
 

Sample Output
Case 1: 1Case 2: -1
 

Author
iSea@WHU
 

Source
The 6th Central China Invitational Programming Contest and 9th Wuhan University Programming Contest Final

题意:给两个数m,n,求使m,n加上一个数后变成两个相邻数素数的最小数
时间限制是2S,可以直接暴力求解,问题是素数打表范围该怎么考虑,因为m,n<=150,打表范围应该到任意m-n(m-n为偶数,1除外)都能找到对应的两个素数差值等于m-n
可以暴力打表先找一找规律

void prime(){    p[0]=0;    mem(vis,0);    mem(num,0);    for(int i=2;i<=Max;i++)    {        if(!vis[i])p[++p[0]]=i;        for(int j=1;j<=p[0]&&(ll)i*p[j]<=Max;j++)        {            vis[i*p[j]]=1;            if(!(i%p[j]))break;        }    }    for(int i=1;i<p[0];i++)    {        int o=p[i+1]-p[i];        num[o]++;    }    for(int i=0;i<=150;i++)pf("%d ",num[i]);}
若打表到1e7,在后面的只里面仍然有几个连续为0(无法满足条件),打表范围到2e7时,偶数位(加上1)全部不为0,这时就满足条件了
暴力的方式有两种,一种是直接枚举所有相邻素数,求出最小的那个即可

#include<iostream>#include<cstdio>#include<algorithm>#include<cstring>#include<string>#include<stack>#include<queue>#include<deque>#include<set>#include<map>#include<cmath>#include<vector>using namespace std;typedef long long ll;typedef unsigned long long ull;typedef pair<int, int> PII;#define pi acos(-1.0)#define eps 1e-10#define pf printf#define sf scanf#define lson rt<<1,l,m#define rson rt<<1|1,m+1,r#define e tree[rt]#define _s second#define _f first#define all(x) (x).begin,(x).end#define mem(i,a) memset(i,a,sizeof i)#define for0(i,a) for(int (i)=0;(i)<(a);(i)++)#define for1(i,a) for(int (i)=1;(i)<=(a);(i)++)#define mi ((l+r)>>1)#define sqr(x) ((x)*(x))const int inf=0x3f3f3f3f;const int Max=2e7+1;int t,m,n,p[Max/10];bool vis[Max+1];void prime(){    p[0]=0;    mem(vis,0);    for(int i=2;i<=Max;i++)    {        if(!vis[i])p[++p[0]]=i;        for(int j=1;j<=p[0]&&(ll)i*p[j]<=Max;j++)        {            vis[i*p[j]]=1;            if(!(i%p[j]))break;        }    }}int main(){    prime();    sf("%d",&t);    for1(i,t)    {        sf("%d%d",&m,&n);        pf("Case %d: ",i);        if(m>n)swap(m,n);        int ans=-1;        for(int i=2;i<=p[0];i++)            if(p[i]-n>=0&&p[i-1]-m>=0)                if(p[i]-n==p[i-1]-m)                {                    ans=p[i]-n;                    break;                }        pf("%d\n",ans);    }    return 0;}

时间为1300MS比较慢

因为1-150最大差值才149,在素数打表后预处理一下就行,再枚举的话会快很多

#include<iostream>#include<cstdio>#include<algorithm>#include<cstring>#include<string>#include<stack>#include<queue>#include<deque>#include<set>#include<map>#include<cmath>#include<vector>using namespace std;typedef long long ll;typedef unsigned long long ull;typedef pair<int, int> PII;#define pi acos(-1.0)#define eps 1e-10#define pf printf#define sf scanf#define lson rt<<1,l,m#define rson rt<<1|1,m+1,r#define e tree[rt]#define _s second#define _f first#define all(x) (x).begin,(x).end#define mem(i,a) memset(i,a,sizeof i)#define for0(i,a) for(int (i)=0;(i)<(a);(i)++)#define for1(i,a) for(int (i)=1;(i)<=(a);(i)++)#define mi ((l+r)>>1)#define sqr(x) ((x)*(x))const int inf=0x3f3f3f3f;const int Max=2e7+1;bool vis[Max+1];int p[Max/10],num[200],pos[200][200],t,m,n;void prime(){    p[0]=0;    mem(vis,0);    mem(num,0);    for(int i=2;i<=Max;i++)    {        if(!vis[i])p[++p[0]]=i;        for(int j=1;j<=p[0]&&(ll)i*p[j]<=Max;j++)        {            vis[i*p[j]]=1;            if(!(i%p[j]))break;        }    }    for(int i=1;i<p[0];i++)    {        int o=p[i+1]-p[i];        if(o<=150&&num[o]<200)//不需要计算出那么多的素数,一个差值对应200个已经足够了            pos[o][num[o]++]=p[i];    }}int main(){    prime();    sf("%d",&t);    for1(i,t)    {        sf("%d%d",&m,&n);        if(m>n)swap(m,n);        int k=n-m;        int ans=-1;        for(int i=0;i<num[k];i++)            if(pos[k][i]>=m)            {                ans=pos[k][i]-m;                break;            }        pf("Case %d: %d\n",i,ans);    }    return 0;}